Love - Bomberman Concept

From TRCCompSci - AQA Computer Science
Revision as of 10:49, 11 July 2019 by Admin (talk | contribs) (Player Class)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

This will create a Bomberman esque game, in which the player is blocked by bricks and places bombs to remove them. I have tried to make this example very object oriented with classes for Player, Map, and Tile. I have also tried to make most of the code within these classes.

The image resources for this tutorial are these: Bomb.png Brick.png Explosion.png Ground.png Wall.png Bomber.png

Variables

local size = 9
local space = 5
local width = size * 45 + space
local height = size * 45 + space
local range = 2

Tile Class

function Tile(tiletype)
	local self = {
		tiletype=tiletype,
		timer=0
		}
		
	function self.getimage(tiletype)
		return love.graphics.newImage(tiletype..".png")
	end
	
	function self.setimage()
		self.image=self.getimage(self.tiletype)
	end
	
	self.image=self.getimage(tiletype)
	
	return self
end

Map Class

function Map()
	local self = {}
	
	self.map = {}  -- create the Map
    for i=0,size do
		self.map[i] = {}     -- create a new row
		for j=0,size do
			if i%2==1 and j%2==1 then -- every other tile is a wall
				self.map[i][j] = Tile("wall")
			else
				self.map[i][j] = Tile("ground")
			end
		end
    end
	
	self.map[3][2] = Tile("brick") -- set the positions of the bricks
	self.map[4][7] = Tile("brick")
	
	function self.draw() -- draw method cycles through each tile, and draws it to the screen
		for i=0,size do
			for j=0,size do
				love.graphics.draw(self.map[i][j].image,i*45+space,j*45+space)
			end
		end
	end

	end
	
	return self
end

Map Update Method

	
	function self.update(dt) -- this goes inside the Map class above
		for i=0,size do -- cycle through each tile
			for j=0,size do
				tile = self.map[i][j]
				if tile.timer > 0 then -- if the tile timer is above 0 then reduce the timer
					tile.timer=tile.timer-dt
				else -- timer has elapsed
					if tile.tiletype=='explosion' then -- explosions change to ground
						tile.tiletype='ground'
						tile.setimage()
					end
					
					if tile.tiletype=='bomb' then -- bombs change to explosions, timer is seconds
						tile.tiletype='explosion'
						tile.setimage()
						tile.timer=.5
						
						for a=0, 3 do -- the explosions spread in four directions
							if a == 0 then -- if statement to set the angle for each direction
								angle=0
							elseif a== 1 then
								angle = 360
							elseif a== 2 then 
								angle=90
							elseif a== 2 then 
								angle=180
							end
							cosa = math.floor(math.cos(math.rad(angle)))
							sina = math.floor(math.sin(math.rad(angle)))
							for r = 1, range do -- the range of the explosion is in the variables
								xoffset = r * cosa
								yoffset = r * sina


								if i+xoffset >=0 and i+xoffset <=size -- this checks if this explosion is on the screen
								and j+yoffset >=0 and j+yoffset <=size then
									if self.map[i+xoffset][j+yoffset].tiletype ~= "wall" then -- a wall will stop the explosion
										self.map[i+xoffset][j+yoffset].tiletype='explosion'
										self.map[i+xoffset][j+yoffset].setimage()
										self.map[i+xoffset][j+yoffset].timer=.5
									else
										break  -- break to stop the explosion in that direction 
									end
								end

								if i-xoffset >=0 and i-xoffset <=size -- as above but minus the offset
								and j-yoffset >=0 and j-yoffset <=size then
									if self.map[i-xoffset][j-yoffset].tiletype ~= "wall" then
										self.map[i-xoffset][j-yoffset].tiletype='explosion'
										self.map[i-xoffset][j-yoffset].setimage()
										self.map[i-xoffset][j-yoffset].timer=.5
									else 
										break
									end
								end
								
							end
							
						end
					end					
					
				end
			end
		end

Player Class

function Player(startx, starty)
	local self = {
		x=startx, -- x and y for player position
		y=starty,
		timer=0, -- timer is used for key presses
		interval =.3, -- interval for key press timer
		lives = 3,
		deadtimer = 0 -- this will be the time from death, a player can be killed again
	}
	
	self.image = love.graphics.newImage("bomber.png") -- image to use for player
	
	function self.draw()
		love.graphics.draw(self.image,self.x*45+space,self.y*45+space) -- draw player at current position
	end
	
	return self
end

Player Update Method

	function self.update(dt, gamemap) -- this should be part of the player class above
		local x = self.x -- store the current x & y locally
		local y = self.y -- these will be used to reset the position if needed
		
		if self.deadtimer > 0 then -- player has died and cant die again until this runs out
			self.deadtimer = self.deadtimer - dt
		end
		
		if self.timer<=0 then -- this timer controls key presses, so that only one press is registered 
			if love.keyboard.isDown('a') then 
				self.x = self.x - 1
				self.timer=self.interval				
			elseif love.keyboard.isDown('d') then 
				self.x = self.x + 1
				self.timer=self.interval	
			elseif love.keyboard.isDown('w') then 
				self.y = self.y - 1	
				self.timer=self.interval	
			elseif love.keyboard.isDown('s') then 
				self.y = self.y + 1
				self.timer=self.interval
			end
		else
			self.timer = self.timer - dt -- key press timer still active, so minus delta time
		end
		
		if self.x >= 0 and self.x <= size-1
			and self.y >= 0 and self.y <= size-1 then -- check the movement is within the map
			if gamemap.map[self.x][self.y].tiletype~= "ground" then -- check the new position is a ground tile
				self.x=x -- if not reset position
				self.y=y
			end
		else
			self.x=x -- player move not on map so reset position
			self.y=y
		end
		
		if love.keyboard.isDown('b') and gamemap.map[self.x][self.y].tiletype == "ground" then -- drop bomb
			gamemap.map[self.x][self.y].tiletype= "bomb"
			gamemap.map[self.x][self.y].setimage()
			gamemap.map[self.x][self.y].timer=3 -- seconds before the bomb explodes
		end
		
		if gamemap.map[self.x][self.y].tiletype== "explosion" and self.deadtimer <= 0 then -- player hit by explosion
			self.x=0 -- reset back to start
			self.y=0
			self.lives = self.lives-1 -- reduce lives
			self.deadtimer=1 -- 1 second before the player can die again
			print ("lives "..self.lives)
		end		
	end

LOVE Load, Update, Draw

function love.load()
	love.window.setMode(width, height)
	gamemap = Map()
	player = Player(0,0)
end

function love.update(dt)
	player.update(dt, gamemap)
	gamemap.update(dt)
end
 
function love.draw()
	gamemap.draw()
	player.draw()
end