03-29-2024, 09:00 AM
(This post was last modified: 03-29-2024, 09:46 AM by kevin.
Edit Reason: Add the control keys
)
(03-29-2024, 07:40 AM)kevin Wrote: Great - this is a nice challenge. I have a couple of ideas that I will test today. In the meantime, it would be very interesting to see anyone else's solutions.....
Hi Johnno, my first attempt is attached at the bottom of this post. And here is the code:
Code:
visible screen_w = 640,screen_h = 480
'Open a window
set window "Landscape collision",screen_w,screen_h
'enable double buffering
set redraw off
visible bg_image = loadimage("bg.png")
visible points = [];initiate_points()
'visible spaceship = []
visible spaceship = [x:screen_w / 2,y:130,w:32,h:96,dx:0,dy:0]
############ to calculate FPS ##########################
visible framecount,lasttime = 999,fps,frametime = 0,starttime = 0,endtime = 0,min_fps = 99999,max_fps = 0
##########################################################
##############################################################################################
####################################### GAME LOOP #########################################
##############################################################################################
do
### for FPS calc #########
framecount = framecount + 1
starttime = clock()
###########################
spaceship.dx = 0;spaceship.dy = 0
if keydown(KEY_LEFT) then spaceship.dx = -1
if keydown(KEY_RIGHT) then spaceship.dx = 1
if keydown(KEY_UP) then spaceship.dy = -2
if keydown(KEY_DOWN) then spaceship.dy = 2
move_and_check_collision()
'gravity
spaceship.y = spaceship.y + 1
'clear the screen
set color 255,255,255
cls
draw image bg_image,0,0
set color 0,0,255
draw rect spaceship.x,spaceship.y,spaceship.w,spaceship.h,1
set color 0,0,0
set caret 30,10
set justification left
write "mouse = " + mousex() + " / " + mousey();wln
write "FPS = " + str(fps);wln
write "MIN_FPS = " + str(min_fps);wln
write "MAX_FPS = " + str(max_fps);wln
write "sizeof(points) " + sizeof(points);wln
'copy back buffer to the screen
redraw
col2 = pixel(2,screen_h - 10)
'cap FPS to 60
fwait 1000
####### FPS calc ############################
endtime = clock()
frametime = frametime + endtime - starttime
if frametime > 1000 # 1 second
fps = framecount
framecount = 0
frametime = 0
if fps < min_fps then min_fps = fps
if fps > max_fps then max_fps = fps
endif
################################################
until keydown(KEY_ESCAPE)
#########################################################################################
################################# FUNCTIONS ###########################################
#########################################################################################
function initiate_points()
x = 0
while x < screen_w - 1
set color 0,0,0
cls
set color 255,255,255
draw image bg_image,0,0
for x = 0 to screen_w - 1
for y = screen_h - 1 to 0 step - 1
col = pixel(x,y)
if col[0] = 255 and col[1] = 255 and col[2] = 255
points[sizeof(points)] = [x,y]
break
endif
next
next
redraw
wend
endfunc
'==========================================================
function move_and_check_collision()
spaceship.x = spaceship.x + spaceship.dx
spaceship.y = spaceship.y + spaceship.dy
if spaceship.x < 0 then spaceship.x = 0
if spaceship.x + spaceship.w > screen_w then spaceship.x = screen_w - spaceship.w
for x = spaceship.x to spaceship.x + spaceship.w
if x < screen_w
if points[x][1] < spaceship.y + spaceship.h
pln"collision"
spaceship.y = points[x][1] - spaceship.h
endif
endif
next
pln ""
endfunc
'==========================================================
I've used a different background image, as I wanted to simplify it - this code needs a background where for each pixel across the screen, the top of the landscape only appears once.
You can move the "spaceship" with the arrow keys.
What the code does:
- creates a table of 640 elements (screen width) which records the y value of the top of the landscape for each of the 640 x values across the screen - it does this by checking for the colour of the "sky". As this table is created before the main program runs, it does not slow it down at all.
- when the main program is running, there is a collision check for the spacecraft against the landscape. It only looks at 32 elements (the width of the spaceship) of the table created above on each cycle, so should be reasonably efficient.
I'm getting comfortably over 200 fps on my ancient laptop. Please let me know what you think, and if a different approach may be needed?
All the best - Kevin.
landscape collision.zip (Size: 5.61 KB / Downloads: 4)