Not logged inGosu Forums
Forum back to libgosu.org Help Search Register Login
Up Forum
Search
Topic Changing the level in a game By Acturus Date 2019-08-25 19:49
require 'gosu'
require_relative 'credit'
require_relative 'player'
require_relative 'enemy'
require_relative 'bullet'
require_relative 'explosion'
require_relative 'score'
require_relative 'boss'
require_relative 'bossbullet'

class SectorFive < Gosu::Window
# THE BELOW VARIABLES ARE CALLED CONSTANTS
  WIDTH =  800
  HEIGHT = 600
  #ENEMY_FREQUENCY = 0.005
  MAX_ENEMIES = 10000
  EXPIRE = 180

# THE INITIALIZE METHOD STARTS THE INITIAL GAME AND SETS THE SCENE :START

  def initialize
    super(WIDTH, HEIGHT)
    self.caption =  "Sector Five"
    @background_image = Gosu::Image.new('ima/start.png')
    @start_music = Gosu::Song.new('sounds/heart.ogg')
    @start_music.play(true)
    @scene = :start
  end

# THIS METHOD CALLS THE DIFFERENT DRAW METHOD DEPENDING ON WHICH PART IN THE
# GAME THE PLAYER IS AT>> START< GAME < END

  def  draw
    case @scene
        when:start
            draw_start
        when:game
            draw_game
        when:level
            draw_level
        when:end
            draw_end
     end
   end

# THIS METHOD DRAWS THE BACKGROUND IMAGE DURING THE START WINDOW
def draw_start
@background_image.draw(0,0,0)
end

# THIS  METHOD DRAWS THE IMAGES ON THE  WINDOW

def draw_game
   @player.draw
   @background_image.draw(0,0,0)
   @score_board.draw_text("Score=#{@enemies_destroyed}",40,40,1,1,1,Gosu::Color::AQUA)
   @time.draw_text("Time=#{@countdown}",650,40,1,1,1,Gosu::Color::RED)
   @time.draw_text("Health#{@bosshealth}",50,500,1,1,1,Gosu::Color::GREEN)
   @score_board.draw_text("Location#{@distance},#{@distance}",400,400,1,1,1,Gosu::Color::AQUA)

   @time.draw_text("level#{@wave_count}",460,460,1,1,1,Gosu::Color::GREEN)

@enemies.each  do |enemy|
         enemy.draw
   end
   @enemybullets.each do |bullet|
         bullet.draw
   end
   @bullets.each do |bullet|
     bullet.draw_two
   end
   @explosions.each do |explosion|
     explosion.draw
   end
   @playerexplosions.each do |explosion|
     explosion.draw_two
   end
   @boss.each do |b|
     b.draw
   end
   @bossbullets.each do |bullet|
     bullet.draw
   end
end

# THIS METHOD  TELLS THE GAME WHICH UPDATE TO FOLLOW DEPENDING ON WHICH PART
# THE GAME IS ON. GAME OR END

def update
  case @scene
  when :game
    update_game
  when :end
    update_end
  end
end

# THIS METHOD SPECIFIES THE DIFFERENT USABLE BUTTONS DEPENDING ON WHICH  PART
# OF THE GAME THE PLAYER IS ON. START < GAME < END

def button_down(id)
  case @scene
when :start
   button_down_start(id)
when :game
   button_down_game(id)
when :level
   button_down_level(id)
when :end
   button_down_end(id)
end
end

# THIS METHOD STARTS THE GAME

def button_down_start(id)
initialize_game
end

# THIS METHOD CONTAINS  ALL THE VARIABLES TO BE MANIPULATED

def initialize_game
   @background_image = Gosu::Image.new('ima/space.png')
   @player = Player.new(self)
   @enemy_frequency = 0.0
   @boss = []
   @bosshealth = 0
   @enemies = []
   @bullets = []
   @enemybullets = []
   @bossbullets = []
   @random_enemy_bullets = []
   @explosions = []
   @playerexplosions = []
   @bossexplosions = []
   @framecounter = 0
   @scene = :game
   @enemies_appeared = 0
   @enemies_destroyed = 0
   @credits = []
   @game_music = Gosu::Song.new('sounds/chill.ogg')
   @game_music.play(true)
   @explosion_sound = Gosu::Sample.new('sounds/explosion.ogg')
   @shooting_sound = Gosu::Sample.new('sounds/shoot.ogg')
   @falling_sound = Gosu::Sample.new('sounds/fall.ogg')
   @score_board = Gosu::Font.new(30)
   @counter = 0
   @time = Gosu::Font.new(30)
   @distance = 0
   @distance_two = 0
   @bossbulletdistance = 0
   @turn_r_counter = 0
   @turn_l_counter = 0
   @killedenemies = 100
   @countdown = 10
   @level = update_level
end

def update_game
@countdown -= 1 if @framecounter % 60 == 0
@framecounter += 1
@counter += 1 if @framecounter % 60 == 0
# @enemy_frequency += 0 if @counter % 3600 == 0
@player.turn_left if button_down?(Gosu::KbLeft)
@player.turn_right if  button_down?(Gosu::KbRight)
@player.accelerate if button_down?(Gosu::KbUp)
@player.backward if  button_down?(Gosu::KbDown)
@player.move

   #CREATES THE ENEMEY
  if rand < @enemy_frequency
     @enemies.push Enemy.new(self)
     @enemies_appeared += 1
  end

  #THE BOSS CREATION
  if @framecounter % 900 == 0
    @boss.push Boss.new(self)
    @bosshealth += 100
  end

@boss.each do |b|
   if @boss.length > 1
     @boss.delete b
   end
end

# When A Bullet Hits a Boss AN EXPLOSION IS CREATED
@boss.dup.each do |b|
   @bullets.dup.each do |bullet|
     distance = Gosu.distance(b.x, b.y, bullet.x, bullet.y)
     if distance < b.radius + bullet.radius
       @bullets.delete bullet
       @explosions. push Explosion.new(self, b.x, b.y)
       @enemies_destroyed += 5
       @bosshealth -= 20
       if @bosshealth <= 0
         @boss.delete b
       end
       @explosion_sound.play(0.3)
     end
   end
end

   # ENEMY Fires a bullet
   @enemies.select do |enemy|
     if @framecounter % 600 == 0
       @enemybullets.push Bullet.new(self, @enemies[-1].x, @enemies[-1].y, @enemies[-1].angle)
       if @enemies.length >  3
         @enemybullets.push Bullet.new(self, enemy.x, enemy.y, enemy.angle)
       end
     end
  end

   #Boss Fires A Bullet
   @boss.select do |b|
     if @framecounter % 60 == 0
       @bossbullets.push BBullet.new(self, @boss[-1].x, @boss[-1].y, @boss[-1].angle)
     end
   end

   #Direction of Boss Bullet
@bossbullets.each do |bullet|
@bossbulletdistance = Gosu::distance(@player.x, @player.y, bullet.x, bullet.y)
     @bossbulletdistance < 800
        if @player.x > bullet.x
            bullet.move
        end
        if @player.y < bullet.y
           bullet.move_four
        end
        if @player.x < bullet.x
           bullet.move_three
        end
        if @player.y > bullet.y
           bullet.move_two
        end

        if @bossbulletdistance < bullet.radius + @player.radius
     @bossbullets.delete bullet
   end
end

#  THE BOSS FOLLOWS THE ENEMY
@boss.each do |b|
@distance = Gosu::distance(@player.x, @player.y, b.x, b.y)
x1 = @player.x
y1 = @player.y
x2 = b.x
y2 = b.y
  @distance < 800
    if @player.x > b.x
      b.move
    end
    # if @player.y < b.y
    #   b.move_four
    # end
    # if @player.x < b.x
    #   b.move_three
    # end
    # if @player.y > b.y
    #    b.move_two
    # end
end

#TURN THE BOSS TO THE PLAYER
@boss.each do |b|
@ang = b.angle
b.angle
end

# Detects whether there is a collision between a player bullet and an  enemy.
  @enemies.dup.each do |enemy|
    @bullets.dup.each do  |bullet|
      distance = Gosu.distance(enemy.x, enemy.y, bullet.x, bullet.y)
      if distance < enemy.radius + bullet.radius
        @enemies.delete enemy
        @bullets.delete bullet
        @explosions.push Explosion.new(self, enemy.x, enemy.y)
        @enemies_destroyed += 1
        @explosion_sound.play(0.3)
      end
    end
  end

# DELETES THE EXPLOSIONS AFTER  THE EXPLOSION  ARRAY LENGTH IS GREATER THAN 15
  @explosions.dup.each do |explosion|
   if @explosions.length > 15
    @explosions.delete explosion
    @explosions.delete explosion
  end
end

# DELETES AN ENEMY IF THE ENEMY COMES IN CONTACT WITH AN EXPLOSION
   @explosions.dup.each do |explosion|
     @enemies.dup.each do |enemy|
       distance = Gosu.distance(explosion.x, explosion.y, enemy.x, enemy.y)
       if distance  < explosion.radius + enemy.radius
         @enemies.delete enemy
         @explosions.push Explosion.new(self, enemy.x, enemy.y)
         @enemies_destroyed += 1
         @explosion_sound.play(0.3)
       end
     end
   end

#  CREATES AN  EXPLOSION IF A BULLET TOUCHES AN ENEMY
@enemybullets.each  do |bullet|
distance = Gosu.distance(bullet.x, bullet.y, @player.x, @player.y)
if distance < bullet.radius + @player.radius
   @enemybullets.delete bullet
   @playerexplosions.push Explosion.new(self, @player.x, @player.y)
   @explosion_sound.play(0.3)
end
end
@playerexplosions.dup.each do |explosion|
@explosions.delete explosion unless explosion.finishedtwo
end

# CREATES A SOUND IF AN ENEMY LEAVES SOUTH OF THE GAMEBOARD
  @enemies.dup.each do |enemy|
    if enemy.y > HEIGHT + enemy.radius
      @enemies.delete enemy
      @falling_sound.play(0.2)
    end
  end

# THE BELOW COMMANDS MOVE THE DIFFERENT CLASSES

  @bullets.dup.each do |bullet|
    @bullets.delete bullet unless bullet.onscreen?
  end
  @enemybullets.each do |bullet|
    bullet.enemy_move
  end
  @bullets.each do |bullet|
    bullet.move
  end
  @explosions.each  do |explosion|
    explosion.move
  end
   @playerexplosions.each do |explosion|
     explosion.move
  end
   @enemies.each do |enemy|
      enemy.move
  end

# STARTS THE INITIALIZE_END METHOD DEPENDING IF ONE OF THE  CONDITIONS BELOW IS MET
   initialize_end(:count_reached) if @enemies_appeared > MAX_ENEMIES
   @enemies.each do |enemy|
     distance = Gosu::distance(enemy.x, enemy.y, @player.x, @player.y)

   initialize_end(:hit_by_enemy) if distance < @player.radius + enemy.radius
   end
   initialize_end(:off_top) if @player.y < -@player.radius

   initialize_level(:time_expire) if @countdown == 0
   update_level if @count_down ==  0
end

# CONTROLS THE PLAYERS FIRING MECHONISIM

def button_down_game(id)
if  id == Gosu::KbSpace
   @bullets.push Bullet.new(self, @player.x, @player.y, @player.angle)
   @shooting_sound.play(0.9)
end
end

# THE INITILIALIZE END METHOD CREATES THE MESSAGES AFTER THE GAME IS  OVER

def end_of_level(what)
case what
    when :time_expire
     @message3 = "Congratulations!!! :) You Survived the Swarm"
    when :enemy
     @message4 = " Congratulations!!! :) You Killed all the Enemies"
end
@final_message = "THE NEXT LEVEL WILL BEGIN SOON"
@final_message2 = " OR YOU CAN PRESS P to play again, or Q to quit."
end

def initialize_end(fate)
case fate
when :count_reached
   @message = "You Made it! You destroyed #{@enemies_destroyed} ships"
   @message2 = "and #{100 - @enemies_destroyed} reached the base."

when :hit_by_enemy
   @message = "You were struck by an enemy ship"
   @message2 = "Before your ship was destroyed, "
   @message2 += "you took out #{@enemies_destroyed} enemy ships!"

when :off_top
   @message = "You got too close to the enemy mothership."
   @message2 = "Before your ship was destroyed, "
   @message2 += "you took out #{@enemies_destroyed} enemy ships!"
end
@bottom_message = "Press P to play again, or Q to quit."
@message_font = Gosu::Font.new(28)
y = 700

# THIS FUNCTION FILE.OPEN LINKS TO THE FILE WITH THE END CREDIT INFORMATION
# AND APPLIES A  SCROLLING  FUNCTION
File.open('credits.txt').each do |line|
   @credits.push(Credit.new(self,line.chomp,100,y))
   y+=30
end

#>>> @SCENE CHANGES TO :END
@scene = :end
@end_music = Gosu::Song.new('sounds/mind.ogg')
@end_music.play(true)
end

# THIS PART DRAWS THE  SCORE ON THE TOP LEFT  CORNER OF THE WINDOW
def score_counter
  clip_to(50,140,700,360) do
    @score += 1 if @enemies_destroyed +=1
    @score.draw
  end
end

# THIS METHOD PLACES THE FILE INFORMATION IN THE MIDDLE OF THE SCREEN
def draw_end
  clip_to(50,140,700,360) do
         @credits.each do |credit|
             credit.draw
          end
        end
# THIS  PORTION OF THE METHOD ADDS COLOR TO THE  TEXT AND SEPARATES
# PIECES OF THE WINDOW USING LINES>
draw_line(10,140,Gosu::Color::GREEN,WIDTH,140,Gosu::Color::RED)
@message_font.draw(@message,40,40,1,1,1,Gosu::Color::FUCHSIA)
@message_font.draw(@message2,40,75,1,1,1,Gosu::Color::FUCHSIA)
draw_line(0,500,Gosu::Color::GREEN,WIDTH,500,Gosu::Color::RED)
@message_font.draw(@bottom_message,180,540,1,1,1,Gosu::Color::AQUA)
end

# THIS PORTION CALLS THE  MOVE METHOD FROM THE  CREDITS FILE
def update_end
@credits.each do |credit|
   credit.move
end
if @credits.last.y < 150
    @credits.each do |credit|
     credit.reset
   end
end
end

# COMMANDS THE GAME TO RUN AGAIN IF PLAYER PRESSES "P" OR QUIT GAME IF THE
# PLAYER PRESSES "Q"

def button_down_end(id)
  if id == Gosu::KbP
     initialize_game
   elsif id  == Gosu::KbQ
     close
   end
end
end

def initialize_level(medium)

  case medium
  when :time_expire
    @message_three = "You survived wave number #{@level}. Congratualations!
    Prepare for the next level by Pressing P!"
    @message_font_two = Gosu::Font.new(40)
    @scene = :level
  end

end

  def draw_level
    @message_font_two.draw(@message_three,30,300,1,1,1,Gosu::Color::FUCHSIA)
  end

  def update_level
    @wave_count = 0
    if @scene = :game
      @wave_count += 1
    end
    return @wave_count
  end

  def button_down_level(id)
    if id == Gosu::KbP
       initialize_game
     end
  end

# THIS FUNCTION OPENS THE WINDOW

window = SectorFive.new
window.show

#THANK YOU!
Topic Changing the level in a game By Acturus Date 2019-08-23 23:41
I need to save the level and increase it by one.
Topic Changing the level in a game By Acturus Date 2019-08-23 10:37
Thank you for your response. 

So I put the instance variable in the input  method and  increment the level in  the update game method, but it still doesn't save it. After   @scene = :game runs through its cycle all changes  are erased and the game moves to @scene = :level or @scene = :end. I need the program to save the changes that occur in @scene = :game. How can I do this? 

Acturus
Topic How do I make an enemy target a moving player and fire? By Acturus Date 2019-08-22 21:19
Thank you!
Topic Changing the level in a game By Acturus Date 2019-08-22 14:16
So this is my game loop

  def  draw
    case @scene
        when:start
            draw_start
        when:game
            draw_game
        when:level
            draw_level
        when:end
            draw_end
     end
   end

However, I can't save the level that the game is on. How do I that? As soon as draw level occurs and the player presses a key the program reverts back  draw game, but the problem is nothing is saved. How do I make the program calculate the number of times draw_game occurs and save that value  throughout the life of the program?

Thank you,

Acturus
Topic How do I make an enemy target a moving player and fire? By Acturus Date 2019-08-10 15:35
I can make an enemy chase the player and move around but in terms of changing the enemies angle in the direction of a players location at a given time I'm clueless. So how do you get a player to turn its angle to the center of a player's location?

Thank You,

Jordan

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill