lunes, 25 de junio de 2012

Juego de Bolos en C/C++ (Allegro)


El año pasado hice este mini-juego por diversión y revisando el disco duro lo encontré y decidí compartirlo con ustedes, el código no es el mejor pero puede servir de ejemplo para alguien que este interesado en programar juegos con Allegro. Allegro es una librería gráfica multiplataforma así que solo compilen el código en linux/mac o abran el proyecto de Devc++ en window$. Si no es mas acá les dejo el código:

Descargar rapidshare
Descargar mediafire

Nota: para compilar en linux deben agregar `allegro-config --libs` como argumentos en gcc al (o g++) al momento de compilar.

He empezado con un proyecto en android, asi que si me da tiempo publicare tutoriales para crear juegos en C/C++ con Allegro.
Saludos

martes, 19 de junio de 2012

Calcular determinante de una matriz NxM - Java

Aquí les dejo un algoritmo genérico para calcular determinante con cualquier matriz de dimensiones NxM. En esta ocacion en lenguaje Java, pero es facilmente adaptable a cualquier otro lenguaje. Espero le sea útil a alguien.
package calcularDeterminantes;

public class Determinantes {
 
    public int calDeterminante (int [][] matriz)
    {
        int determinante = 0;
        int filas = matriz.length;
        int columnas = matriz[0].length;

        // En caso de que sea una matriz 1x1
        if ((filas==1) && (columnas==1))
        return matriz[0][0];

        int signo=1;
        for (int col=0;col<columnas;col++)
        {
             int[][] submatriz = getSubmatriz(matriz, filas, columnas, col);
             determinante = determinante + signo*matriz[0][col]*calDeterminante(submatriz);
  signo*=-1;
        }
            return determinante;
    }

    public int[][] getSubmatriz(int[][] matriz,int filas,int col,int columna) {
  
         int [][] submatriz = new int[filas-1][col-1];
         int contador=0;
  
         for (int x=0;x<col;x++)
         {
             if (x==col) continue;         
             for (int y=1;y<filas;y++){
                 submatriz[y-1][contador]=matriz[y][x];
             }
         contador++;
         }
  return submatriz;
 }
}

Scripts útiles en bash

Llevaba tiempo sin actualizar el blog, me disculpo por eso la universidad me quitó mucho tiempo con ecuaciones diferenciales y física II, pero ya estoy de vuelta. Esta vez traigo un par de scripts personales que me han facilitado la vida, veamos:

El primero es esencial para mi, programa la maquina para apagarla en "x" minutos, así puedo irme a dormir y continuar descargando algún archivo pesado sin desperdiciar mas energía eléctrica de la necesaria:

#!/bin/bash 
echo "Tiempo de apagado (min): "
read time sudo shutdown -h $time

El segundo es un script que encontre por internet hace un tiempo y le he modificado unos detalles, nos sirve para crear lanzadores en el escritorio (un dolor de cabeza ponerle un icono especifico al eclipse T_T )



#!/bin/bash
read -p "Nombre del lanzador: " NOMBRE # Se nos pide el nombre del lanzador. 
if [ -e /usr/share/applications/$NOMBRE.desktop ]; then # Si el lanzador ya existe... echo "ERROR: El lanzador ya existe. Abortado."
exit # ...salimos del script.
fi read -p "Ruta completa del archivo ejecutable: " RUTAEXE # Se nos pide la ruta completa del archivo ejecutable. 
if [ ! -e $RUTAEXE ]; then # Si el archivo ejecutable no existe... 
echo "ERROR: El archivo no existe. Abortado."
exit # ...salimos del script.
elif [ ! -x $RUTAEXE ]; then # O si el archivo no es ejecutable... 
echo "ERROR: El archivo no es ejecutable. Abortado."
exit # ...salimos del script. 
fi read -p "Ruta completa del archivo de icono: " RUTAICO # Se nos pide la ruta completa del archivo de icono. 
if [ ! -e $RUTAICO ]; then # Si el archivo de icono no existe... 
echo "ERROR: El archivo no existe. Abortado."
exit # ...salimos del script. 
fi echo "[Desktop Entry]" > $NOMBRE.desktop # Creamos el archivo lanzador 
echo "Type=Application" >> $NOMBRE.desktop # escribiendo en él los datos
echo "Terminal=false" >> $NOMBRE.desktop # anteriormente facilitados.
echo "Name=$NOMBRE" >> $NOMBRE.desktop 
echo "Exec=$RUTAEXE" >> $NOMBRE.desktop 
echo "Icon=$RUTAICO" >> $NOMBRE.desktop
echo "Lanzador creado."
echo "Ahora se moverá al directorio '/usr/share/applications/'." 
echo "Introduce tu contraseña de 'root' si es necesario."
sudo chown root:root $NOMBRE.desktop # Hacemos que el lanzador pertenezca a root 
sudo mv $NOMBRE.desktop /usr/share/applications/ # se envia al directorio de los lanzadores. 
read -n 1 -p "Finalizado. Pulsa una tecla para salir..." 

viernes, 16 de diciembre de 2011

Arbol binario en C++

El semestre pasado me tope con este concepto, si han buscado un poco sabran que un arbol binario es una estructura de datos util cuando se trata de hacer modelos de procesos en donde se quiere tomar desiciones en uno de los dos sentidos en cara parte del proceso.

Los arboles binarios sirven para realizar bases de datos donde la búsqueda y almacenamiento sean optimos, debido a que en un arbol los datos no se almacenan de forma lineal como una pila o una cola, donde los datos que entran solo se pueden leer en respectivo orden de entrada. Entre otras aplicaciones de los arboles binarios encontramos la encriptación de archivos o la creación de compiladores.

A continuación algunos de los procesos básicos utilizando arboles binarios (al final pueden descargar el código completo)

Nota: los métodos y procedimientos para un árbol binario deben ser recursivos.

Clase para el nodo de información: 
#include <stdlib.h>

class Nodo
{
    public:
        int info;
        Nodo *Llink; //enlace izquierdo
        Nodo *Rlink; //enlace derecho   
        Nodo(int);
        ~Nodo();
};

Nodo::Nodo(int info)
{
    this->info = info;
    Llink = NULL;
    Rlink = NULL;    
}

Nodo::~Nodo()
{ }

Clase para el árbol binario:
#include "nodo.h"
#include <iostream>

using namespace std;

class Arbin
{
    private:
        Nodo *raiz;
        Nodo *Insertar(Nodo*,Nodo*);
        Nodo *Borrar(Nodo*, int);
        int  getInfo_der(Nodo*);
        void preOrden(Nodo*);
        void inOrden(Nodo*);
        void postOrden(Nodo*);
    public:
        Arbin();
        void Crear(Nodo*);
        void Recorridos(int);
        void Eliminar(int);
        ~Arbin();
}; 

Algunos métodos básicos:
Inserción 
Nodo* Arbin::Insertar(Nodo *p, Nodo *q){
    if(p == NULL){
        p = q;
    }
    else{
        if(q->info < p->info){
            p->Llink = Insertar(p->Llink,q);
        }
        else{
            p->Rlink = Insertar(p->Rlink,q);
        }
    }
    
    return p;
}

Recorridos
void Arbin::preOrden(Nodo *p){
    if(p != NULL){
        cout << p->info << ", ";
        preOrden(p->Llink);
        preOrden(p->Rlink);
    }
}

void Arbin::inOrden(Nodo *p){
    if(p != NULL){        
        inOrden(p->Llink);
        cout << p->info << ", ";
        inOrden(p->Rlink);
    }
}

void Arbin::postOrden(Nodo *p){
    if(p != NULL){
        cout << p->info << ", ";
        postOrden(p->Llink);
        postOrden(p->Rlink);
    }
}

Estos solo son algunos métodos, pero pueden descargar el ejemplo completo AQUÍAQUÍ.

Debo agradecer mi profesor de estructura de información, Ricardo Contreras por compartir muchos de estos algoritmos que han sido mejorados por el a lo largo de su experiencia como docente.

miércoles, 14 de diciembre de 2011

Animación hecha con Pygame

Esta vez les presento un segundo ejemplo en python usando la librería gráfica Pygame, esta mas organizado que los anteriores y al final podrán encontrar los links para descargarlo completo.
Este ejemplo a diferencia de los anteriores usa sprites animados, dando la sensación de que el personaje camina; cabe aclarar que es un ejemplo muy sencillo ya que el usuario no interactúa es una simple animación, sin embargo es muy fácil hacer que el personaje se mueva con el teclado si se implementa las instrucciones del teclado del ejemplo anterior.

Se divide en dos archivos: sujetos.py y juego.py


sujetos.py

import pygame

class sujeto(pygame.sprite.Sprite):
    """De esta clase heredan los objetos vivientes"""    
    def __init__(self, imagenes):        
        self.imagenes = imagenes        
        self.frame = 0   
        self.indicador = 30     
        self.rect = self.imagenes[self.frame].get_rect()
        self.rect.top = 300
        self.rect.left = 40        
    def move(self, vx,vy):
        self.rect.move_ip(vx,vy)
    def update(self, superficie):
        superficie.blit(self.imagenes[self.frame],self.rect)   
    def nextFrame(self):  
        self.frame = self.indicador % len(self.imagenes) #controla los indices de las imagenes
        self.indicador+=1   #sigue a la imagen siguiente
    def setNewSprites(self,imagenes):
        self.imagenes = imagenes    
        
class Player(sujeto):
    """Clase del heroe"""
    def __init__(self, imagenes):        
        sujeto.__init__(self,imagenes)        
    def getLife():
        return self.life

juego.py

import pygame
import sujetos
import os

# Constantes
ANCHO = 640
ALTO = 480

# Inicializaciones y variables globales
pygame.init()
screen = pygame.display.set_mode((ANCHO,ALTO))
pygame.display.set_caption("SponjeBob Attack")
reloj = pygame.time.Clock()

# Carga las imagenes
def load_img(nombre, directorio):
    ruta = os.path.join(directorio,nombre)
    try:
        image = pygame.image.load(ruta)
    except:
        print "Error! no se puede cargar la imagen"
    return image.convert_alpha()       

imagenesPlayerDer = [load_img("walkr1.png","Res"),load_img("walkr2.png","Res"),
                     load_img("walkr3.png","Res"),load_img("walkr4.png","Res"),
                     load_img("walkr5.png","Res"),load_img("walkr6.png","Res"),]    
imagenesPlayerIzq = [load_img("walkl1.png","Res"),load_img("walkl2.png","Res"),
                     load_img("walkl3.png","Res"),load_img("walkl4.png","Res"),
                     load_img("walkl5.png","Res"),load_img("walkl6.png","Res"),]
imagenFondo = load_img("fondo.png","Res")
                     
# Pinta las imagenes en la pantalla                     
def paint(player):
    screen.blit(imagenFondo,[0,0])
    player.update(screen)
    pygame.display.update()
    player.nextFrame()

def main():   
        
    spritesRight = True
                            
    player = sujetos.Player(imagenesPlayerDer)    
    exit = False   
    vx = 15
    
    while exit != True:     # Bucle principal
        paint(player)        
        player.move(vx,0)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:                
                exit = True                
        # control de los limites   
        if player.rect.left >= ANCHO or player.rect.left <= 0:
            vx=-vx
            if spritesRight == True:  #si mira hacia la derecha
                player.setNewSprites(imagenesPlayerIzq)
                spritesRight = False
            else: #si mira hacia la izquierda
                player.setNewSprites(imagenesPlayerDer)
                spritesRight = True     
        reloj.tick(12)
    pygame.quit()

# INICIO
if __name__ == '__main__':
    main()



Pueden descargar el código completo con las imagenes aquí o aquí. Esos son módulos base para el juego que publicare próximamente, hasta entonces.

viernes, 9 de diciembre de 2011

Mover un Sprite en Python con Pygame

En esta ocasión vamos a modificar nuestro ejemplo anterior para mejorar el movimiento con el teclado, y mover la imagen como un sprite y no como una simple imagen, mas adelante mencionare las ventajas de esto.

import pygame

negro = (0,0,0)
blanco = (255,255,255) 
arriba,abajo,izq,der = False, False, False, False
exit = False 
speed = 10
vx,vy = 0,0  

class Balon(pygame.sprite.Sprite):
    def __init__(self,imagen):
        self.imagen = imagen
        self.rect=self.imagen.get_rect()
        self.rect.top = 300
        self.rect.left = 320
    def move(self,vx,vy):
        self.rect.move_ip(vx,vy)
    def update(self,superficie):
        superficie.blit(self.imagen,self.rect)

def check_keys(event):
    global vx
    global vy
    global abajo
    global arriba
    global izq
    global der
    global exit
    if event.type == pygame.QUIT:
        exit = True                
    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_UP:
            arriba = True
            vy-= speed
        if event.key == pygame.K_DOWN:
            abajo = True
            vy+= speed
        if event.key == pygame.K_RIGHT:
            der = True
            vx+= speed
        if event.key == pygame.K_LEFT:
            izq = True
            vx-= speed
    if event.type == pygame.KEYUP:
        if event.key == pygame.K_UP:
            arriba = False
            if abajo == True: vy+=speed
            else: vy=0
        if event.key == pygame.K_DOWN:
            abajo = False
            if arriba == True: vy-=speed
            else: vy=0
        if event.key == pygame.K_RIGHT:
            der = False
            if izq == True: vx-=speed
            else: vx=0
        if event.key == pygame.K_LEFT:
            izq = False
            if der == True: vx+=speed
            else: vx=0
def main():    
    pygame.init()
    screen = pygame.display.set_mode((640,480))    
    reloj = pygame.time.Clock()
    pygame.display.set_caption("Ejemplo")
    imgBalon = pygame.image.load("balon.png").convert_alpha()
    fondo = pygame.image.load("fondo.png").convert_alpha()
    balon = Balon(imgBalon)    
    
    while exit!= True:
        for event in pygame.event.get():
             check_keys(event)                      
        screen.blit(fondo,(0,0))
        balon.move(vx,vy)
        balon.update(screen)
        pygame.display.update() 
        reloj.tick(20)       
    pygame.quit()
    
main()


El código se ordeno en varias funciones, se le coloco un titulo a la ventana, se creo una clase especifica para crear el sprite y se agrego una imagen de fondo, en lugar de color sólido. La ventaja de manejar sprites, es que tenemos el rectángulo de la imagen lo que facilita mas adelante la detección de colisiones, y ademas, el movimiento se hace mas sencillo moviendo el rectángulo con move_ip().

Fuentes: ChelinTutorials, Pygame Doc

Mover una imagen con mouse o teclado - Python (Pygame)

Desde hace poco empece con mis estudios en python, y debo decir que es un lenguaje muy cómodo de manejar y fácil de aprender, navegando por ahí encontré un conjunto de módulos python para la creación de videojuegos en 2D que me llamo mucho la atención y empece a investigar. Pygame funciona como interfaz de las bibliotecas SDL, y está orientado al manejo de sprites; realmente se pueden desarrollar videojuegos rápidamente con Pygame así que decidí hacer algunos post sobre ello.

Lo primero es instalar Pygame, en la pagina oficial http://pygame.org/download.shtml descarga la version para tu sistema operativo, si tienes un SO basado en Unix que no aparece en la lista, descarga el source e instalalo manualmente como se muestra continuación:
Abre una terminal como root y ubícate en el directorio donde descargaste pygame y luego ejecuta los siguientes comandos:
# tar -xzvf pygame-1.9.1release.tar.gz
# cd pygame-1.9.1release
# ./configure
# make
# make install

o en debian/ubuntu pueden usar : $ sudo apt-get install python-pygame 

Teniendo Pygame instalado, comencemos con un ejemplo sencillo donde subimos una imagen y la movemos con el teclado:

import pygame

def main():
    pygame.init() #carga los modulos de pygame
    screen = pygame.display.set_mode([640,480])
    imagen = pygame.image.load("balon.png")
    x,y = 0,0 #coordenadas de la imagen
    vx, vy = 0,0 #velocidad en x - y
    arriba, abajo, izq, der = False, False, False, False
    exit = False
    reloj = pygame.time.Clock()
    azul = (0,0,255)


    while exit!= True:  #ciclo principal
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit = True
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_UP:
                    arriba = True
                    vy=-10
                if event.key == pygame.K_DOWN:
                    abajo = True
                    vy=10
                if event.key == pygame.K_RIGHT:
                    der = True
                    vx=10
                if event.key == pygame.K_LEFT:
                    izq = True
                    vx=-10
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_UP:
                    arriba = False
                    vy=0
                if event.key == pygame.K_DOWN:
                    abajo = False
                    vy=0
                if event.key == pygame.K_RIGHT:
                    der = False
                    vx=0
                if event.key == pygame.K_LEFT:
                    izq = False
                    vx=0               
        x+=vx
        y+=vy            
        screen.fill(azul)
        screen.blit(imagen,(x,y))        
        pygame.display.update() 
        reloj.tick(20)       
    pygame.quit()
   
main()  

Explicare un poco el cogido: pygame trabaja con superficies, es decir, con capas donde pintaremos nuestros gráficos, entonces es necesario crear la superficie principal (la ventana) con el método set_mode(resolucion) que recibe como parámetro una lista con la resolución deseada.

De la misma manera, el metodo load(archivoDeImagen) nos devuelve una superficie a partir de un archivo que se pasa como parametro, esta superficie es la imagen balón que mas moveremos con el teclado y el mouse.
La variable "azul" define un color RGB que usaremos para pintar el fondo de dicho color con el método fill(color). La variable "reloj" es un objeto especial en pygame que nos ayuda a fijar un delay en la ejecución del juego, con el método tick(FPS) asignamos los fotogramas por segundo que deseamos.

por ultimo, el método blit(imagen,coordenadas) pinta sobre la superficie, otra superficie las coordenadas deseadas, en este caso en la pantalla(screen) pinta la imagen del balón en las coordenadas x-y.

El resto del código son instrucciones que modificar la posición de la imagen en los ejes dependiendo de los eventos presentados, estos eventos se recorren con la instrucción for event in pygame.event.get(): y verifica que tipo de evento ocurrió para luego aplicar la lógica de los movimientos y el evento de tipo pygame.QUIT indica que el usuario ha hecho click en la "x" para salir.



Si quisiéramos mover la imagen con el mouse es mas sencillo, solo deben borrar (o comentar) las lineas del control del teclado (lineas 16-46), los booleanos (linea 9) y el dibujado (linea 48) y agregar esta linea después de pintar el fondo:
screen.blit(imagen,pygame.mouse.get_pos())

Por último, los invito a repasar la documentación de Pygame que esta muy interesante clickAca.

Fuentes: Wikipedia, ChelinTutorials

martes, 6 de diciembre de 2011

Manejo de ficheros en Python

Un ejemplo sencillo sobre ficheros en Python


import os
productos = []

class producto:
    """ Clase para cada producto """
    ID = 0
    nombre = ""
    cantidad = 0
    def __init__(self, ID, nombre, cantidad ):
        self.ID = ID
        self.nombre = nombre
        self.cantidad = cantidad

def registrarProducto():
    os.system('clear')
    print "="*80,"\t\tREGISTRAR PRODUCTO\n","="*80
    p = producto(long(raw_input("ID: ")),raw_input("Nombre:"),
                  int(raw_input("Cantidad: ")))
    productos.append(p)
    try:
        fichero = open("archivo.txt", "a") #abre un fichero existente
    except:
        fichero = open("archivo.txt","w") #se crea el fichero si no existe   
    fichero.write(str(p.ID)+","+p.nombre+","+ str(p.cantidad)+"\n")   
    fichero.close()
   
def verProductos():
    os.system('clear')
    print "="*80,"\t\tLISTA DE PRODUCTOS\n","="*80
    print "ID/Nombre/cantidad\n"
    try:
        fichero = open("archivo.txt","r")
        for linea in fichero:
            print linea.strip()    
        fichero.close()
    except:
        print "El fichero no existe, porfavor creelo"  

def printMenu():   
    print "="*80,"\t\tMENU\n","="*80   
    print "Escoja una opcion: "   
    print "\t1.Registrar un producto"
    print "\t2.Ver lista de productos"
    print "\t3.salir"   
    return raw_input("OPCION: ") 
        
def menu():
    opcion = 0
    while opcion != '3' :       
        opcion = printMenu()               
        if opcion == '1':
            registrarProducto()
        elif opcion == '2':
            verProductos()
menu()
exit()

sábado, 10 de septiembre de 2011

Figlet - Generador de codigo ASCII en consola

"FIGlet es una aplicación informática que genera banners de texto, en varias tipografías, formadas por letras compuestas por conglomerados de caracteres ASCII más pequeños." Wikipedia.


Instalamos esta aplicacion en Debian ( y derivados ) de forma habitual:


Como root:
# apt-get install figlet


y para probarlo ejecutamos: 
# figlet loQueQuieresVer


Ejemplo:

viernes, 9 de septiembre de 2011

Generar el triangulo de Pascal en C

El siguiente código muestra como generar el triangulo de pascal, el truco para imprimirlo es usar " %3".


#include "stdio.h"

int main(int argc, char *argv[]){

   int pasc[11];
   int n=11;
   int x, i, j;

   x=0;

   //valida el numero de lineas
   for (i=1; i<=n ; i++)
   {
         //Construimos el triangulo de pascal
         for (j=x; j>=0; j--)
         {
             if(j==x || j==0)
             {
                  pasc[j] = 1;
             }
             else
             {
                  pasc[j] = pasc[j] + pasc[j-1];
             }
         }

        x++;
        printf("\n");
        //Truco para imprimir el triangulo
        for (j=1; j<=n-i; j++)
             printf("   ");

        for(j=0; j<x; j++)
        {
             printf("%3d   ", pasc[j]);
        }
   }
return 0;
}
El resultado: