sudo|Xanthippe

But once I caught him when he was open like Silenus' statues, and I had a glimpse of the figures he keeps hidden within: they were so godlike — so bright and beautiful, so utterly amazing — that I no longer had a choice: I just had to do whatever he told me.

Tag: programming

Transforming Raspberry Pi to a game console

Before yesterday I’ve never used Python. I was actually forced to do it because of the fact that it is now official language of Raspberry Pi. After spending one day with it I have to say that it’s amazing and I would recommend it for anyone who want to start programming (not advanced programmer here actually). Yesterday I modified already written Pong clone to use GPIO interface and move paddle when I push a button. Then I thought that it is rather senseless because keyboard can do it better. And then I come up with an idea that it would have sense if there were two players using custom controllers. I decided to write my own Pong clone which I called PiPong! At the end of that post you’ll find a source code. To run it you’ll need to images – for paddle and for ball. You can download package there: http://sourceforge.net/projects/pipong/files/. You can test it also on your computer. To do that, run keypong.py instead of pipong.py, which is made for Raspberry Pi. You’ll need also Pygame which can be downloaded there: http://www.pygame.org/download.shtml If you’re using a 64-bit version of Windows with Python 2.7 or 3.x, there is a binary for you: http://www.lfd.uci.edu/~gohlke/pythonlibs/#pygame

This is how it looks:

# www.sudoxanthippe.wordpress.com
# PiPong!

import pygame, random
from pygame.locals import *
import RPi.GPIO as GPIO
pygame.init()

def menu():
	    
    pygame.init()
    display = True
    
    # Setting resolution
    screen = pygame.display.set_mode((800,600), 0, 24)
    # Hiding mouse
    pygame.mouse.set_visible(False)
    # Setting window's caption
    pygame.display.set_caption("PiPong!")
    # Displaying starting label 
    label = pygame.font.SysFont("Tahoma", 25).render("Press ENTER to start!", 1, (185,0,0))
    # Checking size of the Surface
    background = pygame.Surface(screen.get_size())
    # Returning converted size
    background = background.convert()
    # Filling background with colour
    background.fill((45,45,45))
    
    while display:
        
        for event in pygame.event.get():
        # Checking if RETURN key was pressed    
            if pygame.key.get_pressed()[pygame.locals.K_RETURN]:
		# Go further
                    display = False
        
        # Dealing with the colours of the menu
        color = (200, 200, 200)
        rectangle = pygame.Surface((265, 50))
        rectangle = rectangle.convert()
        rectangle.fill(color)
        # Refreshing menu elements
        screen.blit(background, (0,0))
        screen.blit(rectangle, (264, 280))
        screen.blit(label, (280, 290))
        
        # Update the full display Surface to the screen
        pygame.display.flip()
        
def game():
	pygame.init()
	display = True
	
	# Setting resolution
	screen = pygame.display.set_mode((800,600))
	# Hiding mouse
	pygame.mouse.set_visible(False)
	# Setting window's caption
	pygame.display.set_caption("PiPong!")
	

	# Checking size of the Surface
	background = pygame.Surface(screen.get_size())
	# Returning converted size
	background = background.convert()
	# Filling background with colour
	background.fill((45,45,45))
	
	# Loading images
	sprite_pad = pygame.image.load("pad.png")
	sprite_pad_mirror = pygame.transform.flip(sprite_pad, True, False)
	sprite_ball = pygame.image.load("ball.png")
	
	# Converting images to sprites
	rect_pad1 = sprite_pad.get_rect()
	rect_pad2 = sprite_pad_mirror.get_rect()
	rect_ball = sprite_ball.get_rect()
	
	
	# Ball movement speed
	hspeed = 0
	vspeed = 0
	while hspeed == 0:
		hspeed = random.choice([-4, 4])
	while vspeed == 0:
		vspeed = random.choice([-4, 4])
	slower = 1
	
	score1 = 0
	score2 = 0
	
	pad_y = 300
	pad_y_2 = 300
	
	while display:

		# Ball movement
		slower -= 1
		if slower == 0:
			slower = 5
			
		# Pads movement for keyboard
		if pygame.key.get_pressed()[pygame.locals.K_s]:
			if (pad_y <= 500):
				pad_y = pad_y + 4
		if pygame.key.get_pressed()[pygame.locals.K_w]:
			if (pad_y >= 10):
				pad_y = pad_y - 4
		if pygame.key.get_pressed()[pygame.locals.K_DOWN]:
			if (pad_y_2 <= 500):
				pad_y_2 = pad_y_2 + 4
		if pygame.key.get_pressed()[pygame.locals.K_UP]:
			if (pad_y_2 >= 10):
				pad_y_2 = pad_y_2 - 4
		
		# Pads movement for GPIO		
		if GPIO.input(22):
			if (pad_y <= 500):
				pad_y = pad_y + 4
		if GPIO.input(24):
			if (pad_y >= 10):
				pad_y = pad_y - 4
		if GPIO.input(21):
			if (pad_y_2 <= 500):
				pad_y_2 = pad_y_2 + 4
		if GPIO.input(19):
			if (pad_y_2 >= 10):
				pad_y_2 = pad_y_2 - 4			
								
		# Setting sprites position
		rect_pad1.left = 25
		rect_pad1.top = pad_y
		rect_pad2.left = 750
		rect_pad2.top = pad_y_2
		
		# Score refreshment
		score1_str = str(score1)
		score2_str = str(score2)
		score = pygame.font.SysFont("Tahoma", 18).render(score1_str + ":" + score2_str, 1, (155,122,222))
				
		# Ball movement
		if hspeed < 0:
			if (rect_ball.left + hspeed > 5):
				rect_ball.left += hspeed
				GPIO.output(23, False)
			else:
				rect_ball.left = 400
				rect_ball.top = 300
				score1 = score1 + 1
				GPIO.output(23, True)
		else:
			if (rect_ball.left + hspeed < 750):
				rect_ball.left += hspeed
				GPIO.output(23, False)
			else:
				rect_ball.left = 400
				rect_ball.top = 300
				score2 = score2 + 1
				GPIO.output(23, True)
		if vspeed < 0:
			if (rect_ball.top + vspeed > 5):
				rect_ball.top += vspeed
			else:
				vspeed = -vspeed
		else:
			if (rect_ball.top + vspeed < 550):
				rect_ball.top += vspeed
			else:	
				vspeed = -vspeed

		# Collision detection
		hit = False
		# Pad1
		if ((rect_ball.left >= rect_pad1.left) and \
		(rect_ball.left <= rect_pad1.left + rect_pad1.width) and \
		(rect_ball.top >= rect_pad1.top) and \
		(rect_ball.top <= rect_pad1.top + rect_pad1.height)):
			hit = True
		# Pad2
		if (rect_ball.left >= rect_pad2.left-27) and \
		(rect_ball.top >= rect_pad2.top) and \
		(rect_ball.top <= rect_pad2.top + rect_pad2.height):
			hit = True
			
		# When collision is detected
		if (hit == True):
			if (rect_ball.left > 400):
				rect_ball.left = rect_ball.left - 5
			else:
				rect_ball.left = rect_ball.left + 5
			hspeed = -hspeed

		if pygame.key.get_pressed()[pygame.locals.K_ESCAPE]:
			display = False
		# Killing process
		for event in pygame.event.get():
			if event.type == pygame.QUIT:
				display = False
			if pygame.key.get_pressed()[pygame.locals.K_RETURN]:
			# Go further
				menu()
		
		# Dealing with the colours
		screen.blit(background, (0,0))
		screen.blit(sprite_pad, rect_pad1)
		screen.blit(sprite_ball, rect_ball)
		screen.blit(sprite_pad_mirror, rect_pad2)
		screen.blit(score, (375, 555))
		
		# Update the full display Surface to the screen
		pygame.display.flip()
		
		
def main():
	#GPIO initialize
	GPIO.setmode(GPIO.BOARD)
	GPIO.setup(22, GPIO.IN)
	GPIO.setup(24, GPIO.IN)
	GPIO.setup(21, GPIO.IN)
	GPIO.setup(19, GPIO.IN)
	GPIO.setup(23, GPIO.OUT)
	menu()
	game()

main()
Advertisements

Learning how to use GPIO

GPIO is very cool feature. When I managed to light a diode using it, I decided to check how input works. I made such configuration with switch, diode and resistors:

We’ve got now four wires connected to our RPi – one is ground (GND), one is power (VCC 3.3V), one is output (PIN23) and one is input(PIN24).  The only new thing, when we compare this to configuration from last post, is that now we have a switch connected to the input. Don’t forget to connect it from PIN24 side to GND with 10k resistor. This is how you should connect it to RPi:

Now it’s time to write a python program that will handle it.

Type in console:

cat > button.py

You will create a new file and start to edit its contents so type then:


import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(23, GPIO.OUT)
GPIO.setup(24, GPIO.IN)
test = 0
while True:
           if GPIO.input(24):
                GPIO.output(23, True)
                if test == 0:
                             print 'You pushed the button!'
                             test = 1
            else:
                GPIO.output(23, False)
                test = 0

Then press ctrl + d. You can do that of course with any text editor you want (nano for example). Just make sure that file have such content.

Try to run it:

python button.py

Now if you press the button the led diode should light up and you should see on your screen a message.

Writing dice rolling ircbot in Java (Part I)

Some time ago I needed a bot for rolling dices. I found only one, written in Ruby, which I don’t know at all. That determined me to write my own bot. In that time I was working on Bukkit plugin so I decided to stick to the Java. I found out that there is magnificent API called PircBot. I’m going to show how use it to write your own bot.

Environment I use is Eclipse. I’ll also show here how to configure it.

Let’s begin with creating new project.

Image

Name it and click Finish.

Image

Now you need to right click on src and choose New > Package.

Image

Name it as you wish and click Finish.

Image

Now click with your right button on fresh package and select New > Class. Let’s call it Main to keep everything clear.

Image

Before we start writing our bot we still need to do couple formal tasks. We’ll start from importing PircBot jar to our project. Download newest version of it HERE. When I am writing that article, the newest version is 1.5.0. In archive you will find jar file and folder called javadocs. Let’s start from importing jar to our project.

Click with right mouse button on the top of DiceRoller tree and choose from context menu properties. Then  go to Java Build Path and click on Add External JARs… there.Image

You’ll see window in which you need to show Eclipse localization of pircbot.jar. To maintain order keep it in Eclipse workspace folder. After doing that you should see something like this:

Image

Apply if asked for and go to Javadoc Location now. You’ll find it in same window on left side. Browse again to find its folder.

Image

And there is last thing to do in project properties. We need to show Eclipse which class is our main. But we can’t do yet, we need to write our class.

Close that window and make sure that you are editing Main.java. Inside public class paste this:

public static void main(String[] args) throws Exception {

MyBot bot = new MyBot();
bot.setVerbose(true);
bot.connect(“irc.server.you.want.connect.to”);

bot.joinChannel(“#somechannel”);

}

Eclipse will show you that error occurred but nothing to worry about. It’s because we are referring to non-existent class. It begins with throwing exception mechanism. Java needs to have some instructions held inside it in case there will happen exception. Then we invoke new class, then turns on errors visibility, then connecting to server, then join specific channel.

That is everything we need in our Main class. Now let’s create new one called MyBot.

Begin with adding extension to public class MyBot, modify it like this:

public class MyBot extends PircBot {

}

Now Eclipse should highlight PircBot and show such message:

Image

Click on Import ‘PircBot’ (org.jibble.pircbot) and… It’s done! New import just appeared:

import org.jibble.pircbot.PircBot;

If you copied public class code from here Eclipse could automatically did that import, there is nothing to worry about. Just be sure that you’ve got such import.

Now we need to name our bot. But this inside public class MyBot:

public MyBot() {
this.setName(“Bot”);
}

So whole code should look like:

package roller;

import org.jibble.pircbot.PircBot;

public class MyBot extends PircBot

{
public MyBot()
{
this.setName(“Bot”);
}
}

We’ll. That’s the moment when we can finally check how our bot works.

Remember how we were editing project properties? Let’s go there again. Choose from the menu Run/Debug Settings and then click on New… button.

Select Java Application and click OK.

Image

New window will appear. Call it somehow and then click on Search… button.

Image

In new window you should see you main class. Double click it. Apply and exit. Now we are ready to test our bot out. Right click on your project in Package Explorer on left side and choose Export. Double click Runnable JAR file.

From launch configuration chose class we set as main. In library handling select the option in middle. Choose your export destination and click Finish. That’s it.

Now we need to run it. Connect to server and channel you selected for that test and run command line. Go to catalogue you’ve saved your bot and type:

java -jar bot.jar

In couple seconds bot should appear on channel.

Whole code of MyBot.java:

package roller;

import org.jibble.pircbot.PircBot;

public class MyBot extends PircBot {
 public MyBot()
 {
  this.setName("Bot");
 }

public void onMessage(String channel, String sender,
 String login, String hostname, String message) {

}

}

Mechanism of rolling dices will be shown in part 2.