This repository has been archived by the owner on Apr 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathemscripten_crown.nim
131 lines (108 loc) · 4.6 KB
/
emscripten_crown.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# Developed in 2021 by greenfork
# Adapted for emscripten in 2021 by balenamiaa
import math
import nimraylib_now
const
nimFg: Color = (0xff, 0xc2, 0x00) # Use this shortcut with alpha = 255!
nimBg: Color = (0x17, 0x18, 0x1f)
const
crownSides = 8 # Low-polygon version
centerAngle = 2.0 * PI / crownSides.float # Angle from the center of a circle
lowerRadius = 2.0 # Lower crown circle
upperRadius = lowerRadius * 1.4 # Upper crown circle
mainHeight = lowerRadius * 0.8 # Height without teeth
toothHeight = mainHeight * 1.3 # Height with teeth
toothSkew = 1.2 # Little angle for teeth
var
lowerPoints, upperPoints: array[crownSides, tuple[x, y: float]]
camera = Camera(
position: (5.0, 8.0, 10.0), # Camera position
target: (0.0, 0.0, 0.0), # Camera target it looks-at
up: (0.0, 1.0, 0.0), # Camera up vector (rotation over its axis)
fovy: 45.0, # Camera field-of-view apperture in Y (degrees)
projection: Perspective # Defines projection type, see CameraProjection
)
pause = false # Pausing the game will stop animation
camera.setCameraMode(Orbital) # Several modes available, see CameraMode
initAudioDevice() # Initialize audio device
let music = loadMusicStream("resources/ambient.ogg") # Load WAV audio file
music.playMusicStream()
proc UpdateGameWindow() {.cdecl.} =
if not pause:
camera.addr.updateCamera # Rotate camera
music.updateMusicStream()
if isKeyPressed(Space): # Pressing Space will stop/resume animation
pause = not pause
beginDrawing: # Use drawing functions inside this block
clearBackground(RayWhite) # Set background color
beginMode3D(camera): # Use 3D drawing functions inside this block
drawGrid(10, 1.0)
for i in 0..<crownSides:
# Define 5 points:
# - Current lower circle point
# - Current upper circle point
# - Next lower circle point
# - Next upper circle point
# - Point for peak of crown tooth
let
nexti = if i == crownSides - 1: 0 else: i + 1
lowerCur: Vector3 = (lowerPoints[i].x, 0.0, lowerPoints[i].y)
upperCur: Vector3 = (upperPoints[i].x, mainHeight, upperPoints[i].y)
lowerNext: Vector3 = (lowerPoints[nexti].x, 0.0, lowerPoints[nexti].y)
upperNext: Vector3 = (upperPoints[nexti].x, mainHeight, upperPoints[nexti].y)
tooth: Vector3 = (
(upperCur.x + upperNext.x) / 2.0 * toothSkew,
toothHeight,
(upperCur.z + upperNext.z) / 2.0 * toothSkew
)
# Front polygon (clockwise order)
drawTriangle3D(lowerCur, upperCur, upperNext, nimFg)
drawTriangle3D(lowerCur, upperNext, lowerNext, nimFg)
# Back polygon (counter-clockwise order)
drawTriangle3D(lowerCur, upperNext, upperCur, nimBg)
drawTriangle3D(lowerCur, lowerNext, upperNext, nimBg)
# Wire line for polygons
drawLine3D(lowerCur, upperCur, Gray)
# Crown tooth front triangle (clockwise order)
drawTriangle3D(upperCur, tooth, upperNext, nimFg)
# Crown tooth back triangle (counter-clockwise order)
drawTriangle3D(upperNext, tooth, upperCur, nimBg)
block text:
block:
let
text = "I AM NIM"
fontSize = 60
textWidth = measureText(text, fontSize)
verticalPos = (getScreenHeight().float * 0.4).int
drawText(
text,
(getScreenWidth() - textWidth) div 2, # center
(getScreenHeight() + verticalPos) div 2,
fontSize,
Black
)
block:
let text =
if pause: "Press Space to continue"
else: "Press Space to pause"
drawText(text, 10, 10, 20, Black)
proc main() =
# Get evenly spaced points on the lower and upper circles,
# use Nim's math module for that
for i in 0..<crownSides:
let multiplier = i.float
# Formulas are for 2D space, good enough for 3D since height is always same
lowerPoints[i] = (
x: lowerRadius * cos(centerAngle * multiplier),
y: lowerRadius * sin(centerAngle * multiplier),
)
upperPoints[i] = (
x: upperRadius * cos(centerAngle * multiplier),
y: upperRadius * sin(centerAngle * multiplier),
)
initWindow(800, 600, "[nim]RaylibNow!") # Open window
emscriptenSetMainLoop(UpdateGameWindow, 0, 1)
music.unloadMusicStream() # Unload music stream buffers from RAM
closeAudioDevice() # Close audio device
closeWindow()
when isMainModule: main()