Jump to content
IGNORED

Is Batari BASIC as easy as Pygame or Love for example? SDL frameworks..


koolaidpickle

Recommended Posts

Hello, I am glad I was told about Batari Basic as it seems to be the only retro console that allows high-level language programming (please correct me if wrong as I would love to know) I am currently making a cross platform game which uses the LOVE framework, its using Lua + SDL and here is an example of what I have https://gist.github.com/anonymous/66a485aeedaaf8f89d8c Does Batari Basic resemble any of this as far as how easy it is to draw a sprite (guess you cant do that) or text? How about the game loop? If I had to guess its going to be a lot more complicated...

 

Example code:

love.window.setMode(640, 700, {vsync = false})

-- global vars
screen_width =  love.graphics.getWidth()
screen_height = love.graphics.getHeight()
stage = 0
dt_mark = 0
set_mark = 1
boss_bullet_mark = 1
dt_boss_bullet_mark = 0

-- Creating tables
Level_One = {}
Player = {}
StartScreen = {}
Bullet = {}
Boss = {}
Boss_Bullet = {}

-- Boss
function Boss.init()
	local self = {}
	self.x = 100
	self.y = 100
	self.direction = 1
	self.hit = {255, 0, 0}
	self.safe = {41, 128, 185}
	self.color = self.safe
	self.bullets = {}
	self.image = love.graphics.newImage("img/ellison_rect.png")
	self.hit_sound = love.audio.newSource("sounds/hit.wav")
	self.width = self.image:getWidth()
	self.height = self.image:getHeight()

	function self:draw()
		--love.graphics.setColor(self.color)
		love.graphics.setColor(255, 255, 255)
		love.graphics.draw(self.image, self.x, self.y)
		--love.graphics.rectangle("fill", self.x, self.y, self.width, self.height)		
	end

	function self:update(dt)

		if boss_bullet_mark == 1 then
			dt_boss_bullet_mark = love.timer.getTime()
			boss_bullet_mark = 0
		end

		if love.timer.getTime() > dt_boss_bullet_mark + 0.5 then 
			spawn_boss_bullet(self.x + self.width/2, self.y + self.height, player.x, player.y, self.bullets)
			boss_bullet_mark = 1
		end

		if self.direction == 1 then
			self.x = self.x + 50 * dt
		else
			self.x = self.x - 50 * dt
		end
		if self.x > screen_width - self.width then
			self.direction = 0
		elseif self.x < 0 then
			self.direction = 1
		end
	end

	return self
end

-- Boss Bullet
function Boss_Bullet.init(boss_x, boss_y, dx, dy)

	local self = {}
	self.width = 5
	self.height = 5
	self.x = boss_x
	self.y = boss_y
	self.dx = dx
	self.dy = dy
	self.player_x = player_x
	self.player_y = player_y

	function self:draw()
		love.graphics.setColor(241, 196, 15)
		love.graphics.rectangle("fill", self.x, self.y, self.width, self.height)
	end

	function self:update(dt)
		self.x = self.x + (self.dx * dt)
		self.y = self.y + (self.dy * dt)
		--self.y = self.y + 200 * dt
	end

	return self
end

-- Update the position of the bullets
function update_boss_bullets(boss_bullets, dt)
	for i=#boss_bullets, 1, -1 do 
        bb = boss_bullets[i]
		bb:update(dt) 

		if bb.y > screen_height then
			table.remove(boss_bullets, i)
		end

	end
end

-- Draw all the bullets to the screen
function draw_boss_bullets(boss_bullets)
	for i=#boss_bullets, 1, -1 do 
        bb = boss_bullets[i]
		bb:draw() 
	end
end

function spawn_boss_bullet(boss_x, boss_y, player_x, player_y, boss_bullets)
	local angle = math.atan2((player_y - boss_y), (player_x - boss_x))
	local dx = 100 * math.cos(angle)
    local dy = 100 * math.sin(angle)
	bb = Boss_Bullet.init(boss_x, boss_y, dx, dy)
	table.insert (boss_bullets, bb)
end

-- Level One
function Level_One.init()
	local self = {}
	self.music = love.audio.newSource("sounds/hold_me_back_end.mp3")

	function self:draw()
		love.graphics.setColor(0, 0 , 0)
		love.graphics.rectangle("fill", 0, 0, screen_width, screen_height)
		--love.graphics.setColor(246, 36, 89)
		--love.graphics.print("Current FPS: "..tostring(love.timer.getFPS( )), 10, 10)
	end

	return self
end

-- Player
function Player.init()
	local self = {}
	self.width = 25
	self.height = 25
	self.x = (screen_width/2) - (self.width/2)
	self.y = (screen_height) - (self.height * 2)
	self.bullets = {}
	self.gun_sound = love.audio.newSource("sounds/shot.wav")
	self.bullet_x = self.x - self.width/2
	self.bullet_y = self.y
	self.score = 0
	self.hit_sound = love.audio.newSource("sounds/player_hit.wav")
	self.alive = true
	self.score_font = love.graphics.newFont("font/PressStart2P.ttf", 20)
	self.score_text = "SCORE:"


	function self:draw()
		love.graphics.setColor(127, 140, 141)
		love.graphics.setFont(self.score_font)
		love.graphics.print(self.score_text..tostring(self.score), 10, 10)	
		if self.alive == true then
			love.graphics.setColor(46, 204, 113)
			love.graphics.rectangle("fill", self.x, self.y, self.width, self.height)
		end
	end

	function self:shoot()
		self.bullet_x = (self.x + self.width/2) - (2.5)
		self.bullet_y = self.y
		b = Bullet.init(self.bullet_x, self.bullet_y)
		table.insert (self.bullets, b)
	end

	function self:update(dt)

		if self.x > screen_width - self.width then
			self.x = screen_width - self.width
		end

		if self.x < 0 then
			self.x = 0
		end

		if self.y < 0 then
			self.y = 0
		end

		if self.y > screen_height - self.height then
			self.y = screen_height - self.height
		end

		if love.keyboard.isDown( "up" ) then
		   self.y = self.y - 200 * dt
		end
		if love.keyboard.isDown( "down" ) then
		   self.y = self.y + 200 * dt
		end
		if love.keyboard.isDown( "right" ) then
		   self.x = self.x + 200 * dt
		end
		if love.keyboard.isDown( "left" ) then
		   self.x = self.x - 200 * dt
		end
		if love.keyboard.isDown( "lctrl" ) then
			if set_mark == 1 then
				dt_mark = love.timer.getTime()
				set_mark = 0
		   	end
		   	if love.timer.getTime() > dt_mark + 0.2 then
		   		self:shoot(dt)
		   		self.gun_sound:play()
		   		set_mark = 1
			end
		end
	end

	return self
end

-- Bullet
function Bullet.init(x, y)

	local self = {}
	self.width = 5
	self.height = 5
	self.x = x
	self.y = y

	function self:draw()
		love.graphics.setColor(231, 76, 60)
		love.graphics.rectangle("fill", self.x, self.y, self.width, self.height)
	end

	function self:update(dt)
		self.y = self.y - 500 * dt
	end

	return self
end

-- Update the position of the bullets
function update_bullets(players_bullets, dt)
	for i=#players_bullets, 1, -1 do 
        bullet = players_bullets[i]
		bullet:update(dt) 

		if bullet.y < -10 then
			table.remove(players_bullets, i)
		end

	end
end

-- Draw all the bullets to the screen
function draw_bullets(players_bullets)
	for i=#players_bullets, 1, -1 do 
        bullet = players_bullets[i]
		bullet:draw() 
	end
end

-- Check collisions
function check_collision(player, players_bullets, enemy)
	enemy.color = enemy.safe
	for i=#players_bullets, 1, -1 do 
        bullet = players_bullets[i]
        if (bullet.y >= enemy.y and bullet.y <= (enemy.y + enemy.height) and bullet.x >= enemy.x and bullet.x <= (enemy.x + enemy.width)) then
			table.remove(players_bullets, i)
			enemy.color = enemy.hit
			enemy.hit_sound:play()
			player.score = player.score + 1
        end
	end
end

-- Check boss bullet collisions
function check_boss_bullet_collision(player, boss_bullets)
	if player.alive == true then
		for i=#boss_bullets, 1, -1 do 
	        bb = boss_bullets[i]
	        if (bb.y >= player.y and bb.y <= (player.y + player.height) and bb.x >= player.x and bb.x <= (player.x + player.width)) then
				table.remove(boss_bullets, i)
				player.hit_sound:play()
				player.alive = false
	        end
		end
	end
end

-- Check for game over
function check_game_over(player)
	if player.alive == false then
		game_over_font = love.graphics.newFont("font/PressStart2P.ttf", 40)
		game_over_text = "GAME OVER"
		love.graphics.setColor(231, 76, 60)
		love.graphics.setFont(game_over_font)
		love.graphics.print(game_over_text, (screen_width/2) - (game_over_font:getWidth(game_over_text)/2), (screen_height/2) - (game_over_font:getHeight(game_over_text)/2))
	end
end

-- Start Screen
function StartScreen.init()
	local self = {}
	self.music = love.audio.newSource("sounds/hold_me_back_start.mp3")
	self.start_text = "Tap to Start!"
	self.title_text = "FINAL BOSS"
	self.credit_text = "© 2014 Super Mega Turbo"
	self.screen_font = love.graphics.newFont("font/PressStart2P.ttf", 20)
	self.title_font = love.graphics.newFont("font/PressStart2P.ttf", 40)
	self.credit_font = love.graphics.newFont("font/PressStart2P.ttf", 12)
	self.start_text_width = self.screen_font:getWidth(self.start_text)
	self.start_text_height = self.screen_font:getHeight(self.start_text)	
	self.title_text_width = self.title_font:getWidth(self.title_text)
	self.credit_text_width = self.credit_font:getWidth(self.credit_text)
	self.title_text_height = self.title_font:getHeight(self.title_text)
	self.blink = true
	self.dt = 0

	function self:draw()
		love.graphics.setFont(self.title_font)
		love.graphics.setColor(155, 89, 182)
		love.graphics.print(self.title_text, (screen_width/2) - (self.title_text_width/2), 200)
		love.graphics.setFont(self.credit_font)
		love.graphics.setColor(255, 255, 255)
		love.graphics.print(self.credit_text, (screen_width/2) - (self.credit_text_width/2), (screen_height - 200))
		love.graphics.setFont(self.screen_font)
		love.graphics.setColor(255, 255, 255)
		if self.blink == true then
			love.graphics.print(self.start_text, (screen_width/2) - (self.start_text_width/2), (screen_height/2) - (self.start_text_height/2))
		end
	end

	function self:update(dt)
		self.music:play()
		self.dt = self.dt + dt
		if self.dt > 0.5 then
			self.blink = not self.blink 
			self.dt = self.dt - 0.5
		end
	end

	return self
end

-- Creating instances
start_screen = StartScreen.init()
level_one = Level_One.init()
player = Player.init()
boss = Boss.init()

-- Love game loop
function love.load()
	love.graphics.setBackgroundColor(0,0,0)
end

function love.draw()
	if stage == 0 then 
		start_screen:draw()
	elseif stage == 1 then
		level_one:draw()
		player:draw()
		boss:draw()
		draw_bullets(player.bullets)
		draw_boss_bullets(boss.bullets)
		check_game_over(player)
	end 
end

function love.update(dt)
	if love.keyboard.isDown( "return" ) then
   		stage = 1
	end
	if stage == 0 then
		start_screen:update(dt)
	elseif stage == 1 then
		start_screen.music:stop()
		level_one.music:play()
		level_one.music:setVolume(0.4);
		player:update(dt)
		boss:update(dt)
		update_bullets(player.bullets, dt)
		update_boss_bullets(boss.bullets, dt)
		check_collision(player, player.bullets, boss)
		check_boss_bullet_collision(player, boss.bullets)
	end
end
Link to comment
Share on other sites

Visual batari Basic, the batari Basic IDE, has tools that let you draw sprites and playfields:

 

randomterrain.com/atari-2600-memories-batari-basic-commands.html#ideforbb

 

 

Here is a link to batari Basic code examples on the right side of the page:

 

randomterrain.com/atari-2600-memories-batari-basic-commands.html#example_programs

Link to comment
Share on other sites

Batari Basic as it seems to be the only retro console that allows high-level language programming (please correct me if wrong as I would love to know)

 

You're wrong :), you can program almost all retro in high-level language. Most of them in C language.

 

But for instance for Intellivision you have also the fabulous IntyBasic from nanochess.

Link to comment
Share on other sites

Pickle, keep in mind that when we say "high level," that is relatively speaking. BASIC and C is as high-level as you're going to get, and both come with limitations and make less efficient code than programming in raw Assembly. There is no object-oriented Lua equivalents. You're going to be using global variables and GOTOs.

Link to comment
Share on other sites

You also need to be aware of how limited the hardware on these retro consoles are. Batari Basic (bB) only provides 26 bytes of memory to be used in your program and the background graphics are limited to a 32x12 bitmap of a single color foreground.

 

If you're just looking to produce a cool looking game in a short amount of time then you should stick with the high-level frameworks that you've been using.

 

If you're interested in learning more about writing high performance code and figuring out clever ways to make retro consoles do things they were never intended to do, then you should start with bB and plan on eventually learning assembly.

Link to comment
Share on other sites

You also need to be aware of how limited the hardware on these retro consoles are. Batari Basic (bB) only provides 26 bytes of memory to be used in your program and the background graphics are limited to a 32x12 bitmap of a single color foreground.

That's only true if you don't use Superchip RAM or DPC+.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...