(05-28-2024, 05:58 PM)Marcus Wrote: Here's a zip with the fourth tutorial step included. It's about static billboard sprites.
Question on Example 4
By the way, you may reply when you are free, it's not urgent
click the image to zoom-in
Please zoom-in the attached image :
1. On the EngineA Map Editor, I repositioned the player to (4,15).
When I ran the code, the player was facing the south wall.
How to make him facing to the north room ?
2. What function should I write on the code editor so that I can display player's information :
a. player's coordinates / position (x,y,z)
b. player's angle (in degree/radian) so that I can turn him to face the north room.
05-29-2024, 05:33 AM (This post was last modified: 05-29-2024, 05:42 AM by Marcus.)
(05-29-2024, 04:55 AM)1micha.elok Wrote:
(05-28-2024, 05:58 PM)Marcus Wrote: Here's a zip with the fourth tutorial step included. It's about static billboard sprites.
Question on Example 4
By the way, you may reply when you are free, it's not urgent
click the image to zoom-in
Please zoom-in the attached image :
1. On the EngineA Map Editor, I repositioned the player to (4,15).
When I ran the code, the player was facing the south wall.
How to make him facing to the north room ?
2. What function should I write on the code editor so that I can display player's information :
a. player's coordinates / position (x,y,z)
b. player's angle (in degree/radian) so that I can turn him to face the north room.
Thank you.
The coordinate system in the engine and s3d is a bit wonky. The z axis points into the screen, the x axis right and the y axis down. In the editor's top down view, on the other hand, the x axis points right and the z axis down. That's why a map seems mirrored when you walk through it in a game.
You can use player.SetYaw(radians) to change the player's direction in the xz plane. At the angle 0 radians, which is default, the player is looking down (in the editor's top down view). This is because I use sin(angle) (0) for the x direction and cos(angle) (1) for the z direction. So to make the player look up (in the editor's coordinate system ...), use player.SetYaw(rad(180)) or player.SetYaw(PI). You could even set the starting angle as "value" in the "player" flag (more about that when we look at enemies, which comes next).
You can read the player's position using the X, Y and Z functions. In your Draw function:
You have to declare the player variable visible for that to work.
I should have decided to let the x axis in the editor represent the 3d z axis and the y axis be the 3d x axis. Then the map wouldn't appear as mirrored when you walk through it. Maybe I will make that change at some point ...
(05-29-2024, 05:33 AM)Marcus Wrote: ...
a map seems mirrored when you walk through it in a game.
...
Don't worry, though the map seems mirrored compared to EngineA Map Editor when we walk through it in a game,
I could make an adjustment on the game's compass and map ...
Starting Point
Player is facing to the North as it's shown on the Compass.
Player's position on the map (4,0,6) click the image to zoom-in
Move To The Left
Player is moving to the left as it's shown on the Compass.
Player's position on the map (9,0,2) click the image to zoom-in
Move to The Right
Player is moving to the right as it's shown on the Compass.
Player's position on the map (2,0,2) click the image to zoom-in
05-29-2024, 05:15 PM (This post was last modified: 05-29-2024, 05:16 PM by Marcus.)
Can I really write a tutorial step for creating super intelligent and beautiful enemies like these in 45 minutes? You'll know, in 45 minutes. If there's no new post today, there'll be one tomorrow
05-29-2024, 08:27 PM (This post was last modified: 05-29-2024, 08:34 PM by Marcus.)
(05-29-2024, 08:08 PM)johnno56 Wrote: I had a few minutes to spare... I figured if you are going to go with "Jack-o-lanterns"... Moo Ha Ha Ha...
Will not be offended if not used... Just a bit of fun...
J
Much better! Maybe his mouth and eyes could light up like that right before he shoots a fire ball at the player? Yes, I'll let that be the sixth step/example. I was s bit unsure about what to do next. I was thinking about sprites with visual directions (like the enemies in wolfenstein 3d), but that can wait. Enemy and player bullets are more interesting.
(05-29-2024, 06:46 PM)Marcus Wrote: Here you go, tutorial step 5, about really simple moving sprites....
Question on Example 5
Each time new tutorial is released, it's more and more interesting. I like it
I would like to run different scenarios of the pumpkins before and after touching the ground.
Before Touching The Ground click image to zoom in
After Touching The Ground click image to zoom in
Could you please advice me how to do those scenarios ? I have tried to code, but it's failed.
Code:
'----------------
' INITIALIZATION
'----------------
...
'load game assets (pumpkin, map, player)
visible vPumpkinImage1 = loadimage("assets5/pumpkin1.png", 4, 1)
visible vPumpkinImage2 = loadimage("assets5/pumpkin2.png", 4, 1)
..
foreach f in flags
select f.flag
...
case "pumpkin"
o = CreatePumpkinEnemy(f.x, -10, f.z)
EA_AddObject(o)
endsel
next
...
'-----------
' GAME LOOP
'-----------
EA_Run()
'-----------
' FUNCTIONS
'-----------
...
function CreatePumpkinEnemy(x, y, z)
enemy = EA_Object()
'--------------------------------------------------
'It's intended to have different Pumpkin Image
'before touch the ground and after touch the ground
'but it seems failed :(
if enemy.Y()<0
enemy.SetSprite(vPumpkinImage1, 0, true)
enemy.SetHeight(height(vPumpkinImage1)/64)
enemy.SetRadius(0.5*width(vPumpkinImage1)/64)
elseif enemy.Y()>=0
enemy.SetSprite(vPumpkinImage2, 0, true)
enemy.SetHeight(height(vPumpkinImage2)/64)
enemy.SetRadius(0.5*width(vPumpkinImage2)/64)
endif
'--------------------------------------------------
'--------------------------------------------------------------
'It's intended to give different gravity or speed for each enemy
'but it seems failed :(
objs = .SectorObjects()
if objs and sizeof(objs)
for i = 0 to sizeof(objs) - 1
gravity = rnd(0,1)*dt
next
endif
'---------------------------------------------------------------
res = .Move(.DX()*0.75*dt, gravity, .DZ()*0.75*dt, 0)
if res.w 'wall
.SetYaw(rad(deg(atan2(res.dx, res.dz)) - 90 + rnd()*180))
endif
endfunc
return enemy
endfunc
(05-29-2024, 06:46 PM)Marcus Wrote: Here you go, tutorial step 5, about really simple moving sprites....
Question on Example 5
Each time new tutorial is released, it's more and more interesting. I like it
I would like to run different scenarios of the pumpkins before and after touching the ground.
Before Touching The Ground
click image to zoom in
After Touching The Ground
click image to zoom in
Could you please advice me how to do those scenarios ? I have tried to code, but it's failed.
Code:
'----------------
' INITIALIZATION
'----------------
...
'load game assets (pumpkin, map, player)
visible vPumpkinImage1 = loadimage("assets5/pumpkin1.png", 4, 1)
visible vPumpkinImage2 = loadimage("assets5/pumpkin2.png", 4, 1)
..
foreach f in flags
select f.flag
...
case "pumpkin"
o = CreatePumpkinEnemy(f.x, -10, f.z)
EA_AddObject(o)
endsel
next
...
'-----------
' GAME LOOP
'-----------
EA_Run()
'-----------
' FUNCTIONS
'-----------
...
function CreatePumpkinEnemy(x, y, z)
enemy = EA_Object()
'--------------------------------------------------
'It's intended to have different Pumpkin Image
'before touch the ground and after touch the ground
'but it seems failed :(
if enemy.Y()<0
enemy.SetSprite(vPumpkinImage1, 0, true)
enemy.SetHeight(height(vPumpkinImage1)/64)
enemy.SetRadius(0.5*width(vPumpkinImage1)/64)
elseif enemy.Y()>=0
enemy.SetSprite(vPumpkinImage2, 0, true)
enemy.SetHeight(height(vPumpkinImage2)/64)
enemy.SetRadius(0.5*width(vPumpkinImage2)/64)
endif
'--------------------------------------------------
'--------------------------------------------------------------
'It's intended to give different gravity or speed for each enemy
'but it seems failed :(
objs = .SectorObjects()
if objs and sizeof(objs)
for i = 0 to sizeof(objs) - 1
gravity = rnd(0,1)*dt
next
endif
'---------------------------------------------------------------
res = .Move(.DX()*0.75*dt, gravity, .DZ()*0.75*dt, 0)
if res.w 'wall
.SetYaw(rad(deg(atan2(res.dx, res.dz)) - 90 + rnd()*180))
endif
endfunc
return enemy
endfunc
I've made some changes to the code and marked them with Marcus
Code:
'----------------
' INITIALIZATION
'----------------
include "libs/enginea.n7"
set window "test_ex5", 320, 200, false, 3
set redraw off
EA_SetView(primary, rad(90), 0.05, 50)
'load game assets (pumpkin, map, player)
visible vPumpkinImage1 = loadimage("assets5/pumpkin1.png", 4, 1)
visible vPumpkinImage2 = loadimage("assets5/pumpkin2.png", 4, 1)
flags = EA_LoadMap("assets5/map_test5.json")
player = unset
foreach f in flags
select f.flag
case "player"
player = EA_FpsPlayer()
player.SetPos(f.x, f.floorY, f.z)
case "pumpkin"
' Marcus: You might as well use the ceilingY field of the flag. Calling the object
' function Move will push down the enemy to a correct position anyway; you could set it
' to -1000 and the result would be exactly the same.
'o = CreatePumpkinEnemy(f.x, -100, f.z)
o = CreatePumpkinEnemy(f.x, f.ceilingY, f.z)
' EndMarcus
EA_AddObject(o)
endsel
next
EA_AddObject(player)
EA_SetCamera(player)
EA_SetUpdateAction(Update)
'-----------
' GAME LOOP
'-----------
EA_Run()
'-----------
' FUNCTIONS
'-----------
function Update(dt)
if keydown(KEY_ESCAPE, true) EA_Stop()
endfunc
function CreatePumpkinEnemy(x, y, z)
enemy = EA_Object()
'--------------------------------------------------
'It's intended to have different Pumpkin Image
'before touch the ground and after touch the ground
'but it seems failed :(
'if enemy.Y()<0
' enemy.SetSprite(vPumpkinImage1, 0, true)
' enemy.SetHeight(height(vPumpkinImage1)/64)
' enemy.SetRadius(0.5*width(vPumpkinImage1)/64)
'elseif enemy.Y()>=0
' enemy.SetSprite(vPumpkinImage2, 0, true)
' enemy.SetHeight(height(vPumpkinImage2)/64)
' enemy.SetRadius(0.5*width(vPumpkinImage2)/64)
'endif
'--------------------------------------------------
' Marcus: the behavior of this enemy should probably be controlled by a state variable. The
' enemy should behave in one way until it touches the ground, then change state and behave in
' another way.
enemy.state = 0 ' State 0 means it's falling, state 1 will mean it's on the gound.
enemy.SetSprite(vPumpkinImage1, 0, true)
enemy.SetHeight(height(vPumpkinImage1)/64)
enemy.SetRadius(0.5*width(vPumpkinImage1)/64)
' Add a field for vertical speed, random.
enemy.dy = 0.25 + rnd()*1
' EndMarcus
'-------------------------------------------------------
'It's intended to give different gravity for each enemy
'but it seems failed :(
'objs = .SectorObjects()
'if objs and sizeof(objs)
' for i = 0 to sizeof(objs) - 1
' gravity = rnd(0,1)*dt
' next
'endif
'-------------------------------------------------------
' Marcus: do different things depending on the state variable.
if .state = 0 ' Falling from the sky (... ceiling).
' Only move vertically with the speed setup earlier.
res = .Move(0, .dy*dt, 0, 0)
' Check res.g (g as in ground) for collision. It will be true when the enemy collides
' with the ground.
if res.g
' Change state to 1.
.state = 1
' Set "gravity" to 1.
.dy = 1
' Change sprite image. Do the images have the same size? I just assume they do :)
.SetSprite(vPumpkinImage2, 0, true)
endif
else
' Use the dy variable.
res = .Move(.DX()*0.75*dt, .dy, .DZ()*0.75*dt, 0)
if res.w 'wall
.SetYaw(rad(deg(atan2(res.dx, res.dz)) - 90 + rnd()*180))
endif
endif
' EndMarcus
endfunc
return enemy
endfunc