03-02-2024, 01:23 PM
(03-01-2024, 08:05 PM)kevin Wrote:(03-01-2024, 06:32 PM)Marcus Wrote: There's actually a built in command to insert stuff into an existing array. Nope, for some reason it's not documented, and F1 in NED shows no help. But here we go:
Code:points = insert_into_array(points,i + 1,[mousex(),mousey()])
can be done with:
Code:
insert points, i + 1, [mousex(), mousey()]
That's good to know - I thought that it would have been a good command to have, and spent a while going through the documentation. No harm done though - it was a good challenge to write a function for it
When you are considering examples to write for the library, would you consider this, if it is possible with the library? I have code below which is the basis for a space invader type game. Every 2 seconds, an invader is chosen at random, and its state is changed from "active_now" to "diving". What I have been trying to code is for the chosen invader to proceed along the Polyline for a full cycle, and then return to where he would have been in the original invader grid. It would then revert from the state of "diving" back to "active_now". Hope this is clear? Thanks.
Code:include "polyline.n7"
visible screen_w = 640,screen_h = 480
'Open a window
set window "Invaders",screen_w,screen_h
'enable double buffering
set redraw off
'==== set up the invaders ========
visible number_of_invaders = 24
visible invaders = fill([x:0,y:0,w:32,h:16,img:0,x_inc:1,y_inc:20,active_now:true,diving:false],number_of_invaders)
startx = 100
starty = 50
countx = 0
for i = 0 to number_of_invaders - 1
invaders[i].x = startx
invaders[i].y = starty
startx = startx + 40
countx = countx + 1
if countx = 8
countx = 0
startx = 100
starty = starty + 24
endif
next
'========================================
visible spaceship = [x:screen_w / 2,y:screen_h - 80,w:64,h:32]
'========================================
visible spaceship_missiles = []
visible max_spaceship_missiles = 12
'======== polyline stuff ====================
visible points = [[100,100],[100,400],[400,400],[400,100],[100,100]]
' Create a polyline from the points.
visible path = PolyLine(points)
distance = 0
curved = false
speed = 4
timer = 0
############ to calculate FPS ##########################
visible framecount,lasttime = 999,fps,frametime = 0,starttime = 0,endtime = 0
##########################################################
##############################################################################################
####################################### GAME LOOP #########################################
##############################################################################################
do
### for FPS calc #########
framecount = framecount + 1
starttime = clock()
###########################
timer = (timer + 1 ) % 120
if timer = 119 then launch_invader()
move_invaders()
move_spaceship()
'clear the screen
set color 255,255,255
cls
set color 0,0,0
for i = 0 to number_of_invaders - 1
if invaders[i].active_now or invaders[i].diving
if invaders[i].diving = true
draw rect invaders[i].x,invaders[i].y,invaders[i].w,invaders[i].h,false
else
draw rect invaders[i].x,invaders[i].y,invaders[i].w,invaders[i].h,true
endif
endif
next
set color 255,0,0
draw rect spaceship.x,spaceship.y,spaceship.w,spaceship.h
set color 0,0,0
set caret screen_w/2,10
write "mouse = " + mousex() + " / " + mousey();wln
write "FPS = " + str(fps);wln
write sizeof(path)
'copy back buffer to the screen
redraw
'cap FPS to 60
fwait 60
####### FPS calc ############################
endtime = clock()
frametime = frametime + endtime - starttime
if frametime > 1000 # 1 second
fps = framecount
framecount = 0
frametime = 0
endif
################################################
until keydown(KEY_ESCAPE)
#########################################################################################
################################# FUNCTIONS ###########################################
#########################################################################################
function move_invaders()
for i = 0 to number_of_invaders - 1
if invaders[i].active_now or invaders[i].diving
invaders[i].x = invaders[i].x + invaders[i].x_inc
if invaders[i].x > screen_w - invaders[i].w * 2 or invaders[i].x < invaders[i].w
for j = 0 to number_of_invaders - 1
invaders[j].x_inc = - invaders[j].x_inc
invaders[j].y = invaders[j].y + invaders[j].y_inc
next
endif
endif
next
endfunc
################################################
function move_spaceship()
if keydown(KEY_LEFT) then spaceship.x = max(spaceship.x - 2,0)
if keydown(KEY_RIGHT) then spaceship.x = min(spaceship.x + 2,screen_w - spaceship.w)
endfunc
################################################
function launch_invader()
possible_diver = []
selected_diver = 9999
for p = 0 to number_of_invaders - 1
if invaders[p].active_now
possible_diver[sizeof(possible_diver)] = p
endif
next
selected_diver = rnd(sizeof(possible_diver))
invaders[selected_diver].diving = true
invaders[selected_diver].active_now = false
endfunc
################################################
I've added some functions to a polyline so that you can access and modify its control points. The new polyline.n7 is attached to this post. I also took the liberty to add code for diving enemies to your game. I've marked all changes with "Marcus"
Code:
include "polyline.n7"
visible screen_w = 640,screen_h = 480
'Open a window
set window "Invaders",screen_w,screen_h
'enable double buffering
set redraw off
'==== set up the invaders ========
visible number_of_invaders = 24
visible invaders = fill([x:0,y:0,w:32,h:16,img:0,x_inc:1,y_inc:20,active_now:true,diving:false],number_of_invaders)
startx = 100
starty = 50
countx = 0
for i = 0 to number_of_invaders - 1
invaders[i].x = startx
invaders[i].y = starty
startx = startx + 40
countx = countx + 1
if countx = 8
countx = 0
startx = 100
starty = starty + 24
endif
next
'========================================
visible spaceship = [x:screen_w / 2,y:screen_h - 80,w:64,h:32]
'========================================
visible spaceship_missiles = []
visible max_spaceship_missiles = 12
'======== polyline stuff ====================
visible points = [[100,100],[100,400],[400,400],[400,100],[100,100]]
' Create a polyline from the points.
visible path = PolyLine(points)
distance = 0
curved = false
speed = 4
timer = 0
############ to calculate FPS ##########################
visible framecount,lasttime = 999,fps,frametime = 0,starttime = 0,endtime = 0
##########################################################
##############################################################################################
####################################### GAME LOOP #########################################
##############################################################################################
do
### for FPS calc #########
framecount = framecount + 1
starttime = clock()
###########################
timer = (timer + 1 ) % 120
if timer = 119 then launch_invader()
move_invaders()
move_spaceship()
'clear the screen
set color 255,255,255
cls
set color 0,0,0
for i = 0 to number_of_invaders - 1
if invaders[i].active_now or invaders[i].diving
if invaders[i].diving = true
draw rect invaders[i].x,invaders[i].y,invaders[i].w,invaders[i].h,false
' Marcus
draw rect invaders[i].dive_x, invaders[i].dive_y, invaders[i].w, invaders[i].h, true
' EndMarcus
else
draw rect invaders[i].x,invaders[i].y,invaders[i].w,invaders[i].h,true
endif
endif
next
set color 255,0,0
draw rect spaceship.x,spaceship.y,spaceship.w,spaceship.h
set color 0,0,0
set caret screen_w/2,10
write "mouse = " + mousex() + " / " + mousey();wln
write "FPS = " + str(fps);wln
write sizeof(path)
'copy back buffer to the screen
redraw
'cap FPS to 60
fwait 60
####### FPS calc ############################
endtime = clock()
frametime = frametime + endtime - starttime
if frametime > 1000 # 1 second
fps = framecount
framecount = 0
frametime = 0
endif
################################################
until keydown(KEY_ESCAPE)
#########################################################################################
################################# FUNCTIONS ###########################################
#########################################################################################
function move_invaders()
for i = 0 to number_of_invaders - 1
if invaders[i].active_now or invaders[i].diving
invaders[i].x = invaders[i].x + invaders[i].x_inc
if invaders[i].x > screen_w - invaders[i].w * 2 or invaders[i].x < invaders[i].w
for j = 0 to number_of_invaders - 1
invaders[j].x_inc = - invaders[j].x_inc
invaders[j].y = invaders[j].y + invaders[j].y_inc
next
endif
endif
' Marcus
if invaders[i].diving
' Set the last control point of the path to the invaders normal position.
' A problem here is that the regular invaders move vertically with huge steps. This
' doesn't look good for the movement of a diver. So rather than doing this:
'invaders[i].path.ModifyControlPoint(2, invaders[i].x, invaders[i].y)
' , we can interpolate the y coordinate:
y = invaders[i].path.GetControlPoint(2)[1] ' current y of the last control point.
invaders[i].path.ModifyControlPoint(2, invaders[i].x, y*0.95 + invaders[i].y*0.05)
' Move 4 pixels.
invaders[i].path_dist = invaders[i].path_dist + 4
pos = invaders[i].path.GetPoint(invaders[i].path_dist, true)
' Still on path?
if pos
invaders[i].dive_x = pos[0]
invaders[i].dive_y = pos[1]
' No longer diving.
else
invaders[i].active_now = true
invaders[i].diving = false
endif
endif
' EndMarcus
next
endfunc
################################################
function move_spaceship()
if keydown(KEY_LEFT) then spaceship.x = max(spaceship.x - 2,0)
if keydown(KEY_RIGHT) then spaceship.x = min(spaceship.x + 2,screen_w - spaceship.w)
endfunc
################################################
function launch_invader()
possible_diver = []
selected_diver = 9999
for p = 0 to number_of_invaders - 1
if invaders[p].active_now
possible_diver[sizeof(possible_diver)] = p
endif
next
selected_diver = rnd(sizeof(possible_diver))
invaders[selected_diver].diving = true
' Marcus
i = invaders[selected_diver]
' Very simple path, just dive to the bottom center of the screen and back again.
i.path = PolyLine([[i.x, i.y], [width(primary)/2, height(primary) - 20], [i.x, i.y]])
' Set traveled distance to 0.
i.path_dist = 0
' We still need to update the diver's regular position. So when diving, the invader's position is
' stored in dive_x, dive_y. Use these coordinates when drawing and doing collision tests for a
' diving invader.
i.dive_x = i.x
i.dive_y = i.y
' EndMarcus
invaders[selected_diver].active_now = false
endfunc
################################################
Don't hesitate to ask if you find something weird