Skip to content

Instantly share code, notes, and snippets.

@tomfejer
Created October 27, 2019 14:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomfejer/e50762979fe10da42e5b9c0b9a1fa314 to your computer and use it in GitHub Desktop.
Save tomfejer/e50762979fe10da42e5b9c0b9a1fa314 to your computer and use it in GitHub Desktop.
-- character tester
-- by grotandthemob
local game_objects
function _init()
-- create game objects
game_objects={}
-- particles
part={}
-- create player object
make_player(56,104)
for i=1,16 do
make_block(8*i-8,128)
end
end
function _update()
local obj
-- update all the game objects
for obj in all(game_objects) do
obj:update()
end
end
function _draw()
-- clear the screen
cls(1)
-- draw the game ovjects
local obj
for obj in all(game_objects) do
obj:draw()
end
-- write stuff
print("character test room", 8, 8, 13)
print("move:\x8b \x91 fart:\x83", 8, 16, 13)
print("jump:\x97/\x94 accelerate:\x8e", 8, 24, 13)
end
-- game object creation functions
function make_player(x,y)
return make_game_object("player",x,y,{
width=8,
height=8,
move_speed=0.8,
is_standing_on_block=false,
is_facing_left=false,
was_landed=false,
walk_counter=0,
velocity_y=-4,
landing_counter=0,
old_move_speed=move_speed,
update=function(self)
updateparts(self.is_facing_left)
-- update walk counter
if self.walk_counter==0 then
self.walk_counter=8
else
self.walk_counter-=0.5
end
if self.landing_counter == 0 then
self.landing_counter = 0
else
self.landing_counter-=1
end
self.velocity_x*=0.5
-- self.velocity_y*=0.95
-- RIGHT ->
if btn(1) then
self.is_facing_left=false
if self.velocity_x and btn(4) then
-- dusttrail(self.x,self.y)
spawntrail(self.x,self.y)
self.velocity_x+=self.move_speed*2
else
self.velocity_x+=self.move_speed
end
end
-- LEFT <-
if btn(0) then
self.is_facing_left=true
if self.velocity_x and btn(4) then
-- dusttrail(self.x,self.y)
spawntrail(self.x,self.y)
self.velocity_x-=self.move_speed*2
else
self.velocity_x-=self.move_speed
end
end
-- UP ���
if (btn(2) or btn(5)) and self.is_standing_on_block then
self.is_standing_on_block=false
self.was_landed=false
if btn(4) then
self.velocity_y=-self.move_speed*4
for i=1,4 do
dusttrail(self.x,self.y)
end
else
self.velocity_y=-self.move_speed*2
for i=1,2 do
dusttrail(self.x,self.y)
end
end
end
-- DOWN ���
if btn(3) then
self.landing_counter=4
for i=1,2 do
dusttrail(self.x,self.y)
end
end
-- apply gravity
self.velocity_y+=0.3
-- make sure velocity not gets too big
self.velocity_y=mid(-6,self.velocity_y,3)
self.x+=self.velocity_x
self.y+=self.velocity_y
-- limit the player to stay visible
if self.x > 115 then
self.x = 115
end
if self.y < 12 then
self.y = 12
end
if self.x < -3 then
self.x = -3
end
if self.y > 128 then
self.y = 128
end
-- check to see if colliding with coin
for_each_game_object("coin", function(coin)
if self:check_for_hit(coin) and not coin.is_collected then
coin.is_collected=true
-- sfx(1)
end
end)
-- check to see if colliding with block
for_each_game_object("block", function(block)
if self:check_for_hit(block) then
-- score=0
-- sfx(2)
end
end)
-- check to see if colliding with blocks
local was_standing_on_block=self.is_standing_on_block
self.is_standing_on_block=false
for_each_game_object("block", function(block)
local collision_dir=self:check_for_collision(block,3.1)
self:handle_collision(block,collision_dir)
if collision_dir=="down" then
self.is_standing_on_block=true
if not was_standing_on_block then
-- sfx(2)
self.was_landed=true
self.landing_counter = 4
for i=1,8 do
dusttrail(self.x,self.y)
end
end
end
end)
end,
draw=function(self)
-- self:draw_bounding_box(7)
local sprite_num
if self.is_standing_on_block then
if self.velocity_x==mid(-0.1,self.velocity_x,0.1) and self.landing_counter==0 then
sprite_num=16
elseif self.walk_counter<4 then
sprite_num=24
else
sprite_num=24
end
else
if self.velocity_y>0 then
sprite_num=20
else
if self.velocity_x < 0.2 and self.velocity_x > -0.2 then
sprite_num=18
else
sprite_num=26
end
end
end
-- particles
drawparts()
-- sprites
spr(sprite_num, self.x,self.y-8,2,2,self.is_facing_left)
-- print(self.landing_counter,0,0,7)
end,
check_for_block_collision=function(self,block)
end
})
end
function make_block(x,y)
return make_game_object("block",x,y,{
width=8,
height=8,
draw=function(self)
spr(3,self.x,self.y)
-- rect(self.x,self.y,self.x+self.width,self.y+self.height,8)
end
})
end
function make_game_object(name,x,y,props)
local obj={
name=name,
x=x,
y=y,
velocity_x=0,
velocity_y=0,
update=function(self)
-- do nothing
end,
draw=function(self)
-- don't draw anything
end,
draw_bounding_box=function(self,color)
rect(self.x,self.y,self.x+self.width,self.y+self.height,color)
end,
center=function(self)
return self.x+self.width/2, self.y+self.height/2
end,
check_for_hit=function(self,other)
return bounding_boxes_overlaping(self,other)
end,
check_for_collision=function(self,other,indent)
--calculate the four hitboxes
local x,y,w,h = self.x,self.y,self.width,self.height
local top_hitbox={x=x+indent,y=y,width=w-2*indent,height=h/2}
local bottom_hitbox={x=x+indent,y=y+h/2,width=w-4,height=h/2}
local left_hitbox={x=x,y=y+indent,width=w/2,height=h-2*indent}
local right_hitbox={x=x+w/2,y=y+indent,width=w/2,height=h-2*indent}
if bounding_boxes_overlaping(bottom_hitbox,other) then
return "down"
elseif bounding_boxes_overlaping(left_hitbox,other) then
return "left"
elseif bounding_boxes_overlaping(right_hitbox,other) then
return "right"
elseif bounding_boxes_overlaping(top_hitbox,other) then
return "up"
end
end,
handle_collision=function(self,other,dir)
if dir=="down" then
self.y=other.y-self.height
if self.velocity_y>0 then
self.velocity_y=0
end
elseif dir=="left" then
self.x=other.x+other.width
if self.velocity_x<0 then
self.velocity_x=0
end
elseif dir=="right" then
self.x=other.x-self.width
if self.velocity_x>0 then
self.velocity_x=0
end
elseif dir=="up" then
self.y=other.y+other.height
if self.velocity_y<0 then
self.velocity_y=0
end
end
end
}
-- add additional properties
local key,value
for key,value in pairs(props) do
obj[key]=value
end
-- add it to the list of game objects
add(game_objects,obj)
-- return game object
return obj
end
-- hit detection
function lines_overlapping(min1,max1,min2,max2)
return max1>min2 and max2>min1
end
function rects_overlapping(left1,top1,right1,bottom1,left2,top2,right2,bottom2)
return lines_overlapping(left1,right1,left2,right2) and lines_overlapping(top1,bottom1,top2,bottom2)
end
function bounding_boxes_overlaping(obj1,obj2)
return rects_overlapping(obj1.x,obj1.y,obj1.x+obj1.width,obj1.y+obj1.height,obj2.x,obj2.y,obj2.x+obj2.width,obj2.y+obj2.height)
end
-- game object helper functions
function for_each_game_object(name,callback)
local obj
for obj in all(game_objects) do
if obj.name==name then
callback(obj)
end
end
end
-- particles
-- add a particle
function addpart(_x,_y,_type,_maxage,_col,_oldcol,_xspeed,_yspeed,_initialr)
local _p = {}
_p.x=_x
_p.y=_y
_p.tpe=_type
_p.mage=_maxage
_p.age=0
_p.col=_col
_p.oldcol=_oldcol
_p.xspeed=_xspeed
_p.yspeed=_yspeed
_p.r=_initialr
add(part,_p)
end
-- spawn a trail particle
function spawntrail(_x,_y)
if rnd()<1 then
local _radius = 3
local _ang = rnd()
local _dx = sin(_ang)*_radius
local _dy = cos(_ang)*_radius
addpart(_x+_dx,_y+_dy,0,10+rnd(5),10,9,0.6,-0.1,2)
end
end
function dusttrail(_x,_y)
if rnd()<1 then
local _radius = 8
-- local _ang = rnd()
-- local _dx = sin(_ang)*_radius
-- local _dy = cos(_ang)*_radius
local _ang = rnd()
local _dx = rnd()*24
local _dy = 4
addpart(_x+_dx-12,_y+_dy,0,20+rnd(5),6,13,0,-(rnd()/2),4)
end
end
function updateparts(is_facing_left)
local _p
for i=#part,1,-1 do
_p=part[i]
_p.age+=1
_p.r-=0.2
if is_facing_left then
_p.x+=_p.xspeed
else
_p.x-=_p.xspeed
end
_p.y+=_p.yspeed
if _p.age > _p.mage then
del(part,part[i])
else
if (_p.age / _p.mage) > 0.5 then
_p.col = _p.oldcol
end
end
end
end
function drawparts()
for i=1,#part do
_p=part[i]
-- pixel particle
if _p.tpe == 0 then
pset(_p.x+8,_p.y+4,_p.col)
circfill(_p.x+8, _p.y+4, _p.r, _p.col)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment