Skip to content

Instantly share code, notes, and snippets.

@yoshikischmitz
Last active December 31, 2015 11:39
Show Gist options
  • Save yoshikischmitz/7981536 to your computer and use it in GitHub Desktop.
Save yoshikischmitz/7981536 to your computer and use it in GitHub Desktop.
#LD28 entry by Takemikazuchi545
require 'gosu'
require 'chunky_png'
require 'pp'
def tile_diff(x, y, zoom_level)
x += $camera_offset_x
y += $camera_offset_y
new_x = ((x - y) * Tile::WIDTH/2 * zoom_level) + 1920/2
new_y = ((x + y) * Tile::HEIGHT/2 * zoom_level) + 1080/2
return new_x, new_y
end
class Tile
WIDTH = 128
HEIGHT = 64
attr_accessor :x, :y, :image, :width, :height
def initialize(window, x, y)
@image = Gosu::Image.new(window, "lib/assets/tile#{rand(5)}.png", false)
@window = window
@x = x
@y = y
end
def draw
x, y = tile_diff(@x, @y, $zoom_level)
@image.draw(x, y, 0, $zoom_level, $zoom_level)
end
end
class Building
attr_accessor :x, :y, :image, :width, :height
def initialize(window, x, y, z_order)
buildings = ["tree", "building"]
@building = Gosu::Image.new(window, "lib/assets/#{buildings[rand(2)]}.png", false)
@window = window
@z_order = z_order
@x = x
@y = y
end
def draw
x, y = tile_diff(@x, @y, $zoom_level)
@building.draw(x,
y - @building.height * $zoom_level + Tile::HEIGHT * $zoom_level,
@z_order,
$zoom_level, $zoom_level)
end
end
class Entity
WIDTH = 128
HEIGHT = 144
def draw
@shadow_offset = -5
x, y = tile_diff(@x, @y, $zoom_level)
unless @view_range_sprite.nil?
@view_range_sprite.draw(x - (@view_range_sprite.width/2* $zoom_level) + (Tile::WIDTH/2* $zoom_level),
y - (@view_range_sprite.height/2 - Tile::HEIGHT/2)*$zoom_level,
0, $zoom_level, $zoom_level)
end
@shadow.draw(x - (@shadow.width/2* $zoom_level) + (Tile::WIDTH/2* $zoom_level),
y + (Tile::HEIGHT * $zoom_level) - (@image.height/2 * $zoom_level) + @shadow_offset * $zoom_level,
@z_order, $zoom_level, $zoom_level)
@image.draw(x,
y - (HEIGHT * $zoom_level) + (Tile::HEIGHT * $zoom_level),
@z_order, $zoom_level, $zoom_level)
end
end
class VictoryCube
WIDTH = 128
HEIGHT = 144
attr_accessor :x, :y
def initialize(window, x, y, z_order)
@image = Gosu::Image.new(window, "lib/assets/victory_cube.png", false)
@x = x
@y = y
@z_order = z_order
end
def draw
x, y = tile_diff(@x, @y, $zoom_level)
@image.draw(x,
y - (HEIGHT * $zoom_level) + (Tile::HEIGHT * $zoom_level),
@z_order, $zoom_level, $zoom_level)
end
end
class Player < Entity
attr_accessor :x, :y, :image, :width, :height, :last_moved
def initialize(window, x, y, z_order)
@image = Gosu::Image.new(window, "lib/assets/cube.png", false)
@shadow = Gosu::Image.new(window, "lib/assets/cube_shadow.png", false)
@window = window
@x = x
@y = y
@z_order = z_order
@last_moved = Gosu::milliseconds
end
def move(x, y, tiles, enemies, buildings)
other_entities = [enemies, buildings]
works = false
tiles.each do |tile|
if tile.x == @x + x and tile.y == @y + y
works = true
end
end
other_entities.each do |entity_list|
entity_list.each do |entity|
if entity.x == @x + x and entity.y == @y + y
works = false
break
end
end
end
if works == true
@x += x
@y += y
$camera_offset_x -= x
$camera_offset_y -= y
@z_order = Math.sqrt((@x*@x) + (@y*@y))
#puts @z_order
end
#puts "camera: #{$camera_offset_x} #{$camera_offset_y}"
end
end
class Enemy < Entity
attr_accessor :x, :y, :image, :width, :height, :last_moved, :path
def initialize(window, x, y, z_order)
@image = Gosu::Image.new(window, "lib/assets/evil_cube.png", false)
@shadow = Gosu::Image.new(window, "lib/assets/evil_shadow.png", false)
@view_range_sprite = Gosu::Image.new(window, "lib/assets/evil_view_range.png", false)
@window = window
@x = x
@y = y
@z_order = z_order
@path = Array.new
@pindex = 0
end
def move
if @pindex == @path.length-1
@pindex = 0
@path.reverse!
end
@y = @path[@pindex][0]
@x = @path[@pindex][1]
@pindex += 1
end
end
class GameWindow < Gosu::Window
def load_level
@tiles = Array.new
@enemies = Array.new
@buildings = Array.new
@game_state = :neutral
@enemy_paths = Array.new
#load enemy paths
File.readlines('lib/levels/enemy_paths').each do |line|
enemy_path = Array.new
a = line.match(/enemy_\d+/).to_s
positions = line[a.length..-1]
positions.slice!(0)
positions.slice!(positions.length-1) #remove trailing brackets
positions.split("][").each do |x|
path_x, path_y = x.split(",")
enemy_path << [path_x.to_i, path_y.to_i]
end
@enemy_paths << enemy_path
end
#load level from PNG
row = 0
column = 0
array = ChunkyPNG::Image.from_file('lib/levels/level_1.png')
enemy_paths_index = 0
array.height.times do |x|
array.row(x).reverse_each do |y|
unless y.to_s(16) == "ffffffff"
@tiles << Tile.new(self, row, column)
end
if y.to_s(16) == "ff0000ff"
#puts "player starts at #{row} #{column}"
@player = Player.new(self, row, column, Math.sqrt((row*row) + (column*column)))
$camera_offset_x = -row
$camera_offset_y = -column
end
if y.to_s(16).include? "ca"
enemy = Enemy.new(self, row, column, Math.sqrt((row*row) + (column*column)))
enemy.path = @enemy_paths[enemy_paths_index]
enemy_paths_index += 1
@enemies << enemy
#puts "added enemy, #{enemy.x} #{enemy.y}"
end
if y.to_s(16).include? "8f"
@victory_cube = VictoryCube.new(self, row, column, Math.sqrt((row*row) + (column*column)))
end
if y.to_s(16).include? "ec"
@buildings << Building.new(self, row, column, Math.sqrt((row*row) + (column*column)))
end
column += 1
end
row += 1
column = 0
end
end
def initialize
super 1920, 1080, false
$zoom_level = 0.5
@key_press = false
load_level
@lose_screen = Gosu::Image.new(self, "lib/assets/lose_screen.png", false)
@start_screen = Gosu::Image.new(self, "lib/assets/start_screen.png", false)
@win_screen = Gosu::Image.new(self, "lib/assets/win_screen.png", false)
#puts "player is at #{@player.x} #{@player.y}"
@p_tile = Gosu::Image.new(self, "lib/assets/player_tile.png", false)
@can_move = true
@game_state = :start
end ##
def update_game
unless button_down? Gosu::KbRight or button_down? Gosu::KbLeft or button_down? Gosu::KbUp or button_down? Gosu::KbDown
@can_move = true
end
if Gosu::milliseconds - @player.last_moved > 200
@key_press = false
if button_down? Gosu::KbRight and @can_move == true
#puts "moving"
@player.move(1, 0, @tiles, @enemies, @buildings)
@player.last_moved = Gosu::milliseconds
@key_press = true
@can_move = false
end
if button_down? Gosu::KbDown and @can_move == true
@player.move(0, 1, @tiles, @enemies, @buildings)
@player.last_moved = Gosu::milliseconds
@key_press = true
@can_move = false
end
if button_down? Gosu::KbLeft and @can_move == true
@player.move(-1, 0, @tiles, @enemies, @buildings)
@player.last_moved = Gosu::milliseconds
@key_press = true
@can_move = false
end
if button_down? Gosu::KbUp and @can_move == true
@player.move(0, -1, @tiles, @enemies, @buildings)
@player.last_moved = Gosu::milliseconds
@key_press = true
@can_move = false
end
if @key_press == false and @can_move == true and Gosu::milliseconds - @player.last_moved > 250
@player.move(rand(-1..1), rand(-1..1), @tiles, @enemies, @buildings)
@player.last_moved = Gosu::milliseconds
@key_press = true
end
if button_down? Gosu::KbQ
$zoom_level -= 0.01
@key_press = true
end
if button_down? Gosu::KbE
$zoom_level += 0.01
end
@enemies.each do |enemy|
enemy.move if @key_press == true
end
end
@enemies.each do |enemy|
if enemy.x + 1 == @player.x
if enemy.y + 1 == @player.y or enemy.y - 1 == @player.y or enemy.y == @player.y
@game_state = :lose
end
elsif enemy.x - 1 == @player.x
if enemy.y + 1 == @player.y or enemy.y - 1 == @player.y or enemy.y == @player.y
@game_state = :lose
end
elsif enemy.x == @player.x
if enemy.y + 1 == @player.y or enemy.y - 1 == @player.y or enemy.y == @player.y
@game_state = :lose
end
end
end
end
def update
if @player.x == @victory_cube.x and @player.y == @victory_cube.y
@game_state = :win
end
unless @game_state == :lose or @game_state == :start or @game_state == :win
update_game
end
if button_down? Gosu::KbEscape and @game_state == :lose
@game_state = :neutral
load_level
end
if button_down? Gosu::KbEscape and @game_state == :start
@game_state = :neutral
end
end
def draw_game
@player.draw
@victory_cube.draw
@tiles.each do |tile|
tile.draw
end
@buildings.each do |building|
building.draw
end
@enemies.each do |enemy|
enemy.draw
end
end
def draw_menu
draw_game
if @game_state == :lose
@lose_screen.draw(0,0,1000)
elsif @game_state == :win
@win_screen.draw(0,0,1000)
else
@start_screen.draw(0,0,1000)
end
end
def draw
if @game_state == :lose or @game_state == :win
draw_menu
elsif @game_state == :start
draw_menu
elsif @game_state == :neutral
draw_game
end
end
end
window = GameWindow.new
window.show
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment