El Blog de Murphy

16 Mayo 2009

Processing 1.0 parte 2

Archivado en: Processing — Etiquetas:, — Julio Cesar Cachay Pérez @ 8:56 am

Avanzamos a la segunda parte de este pequeñisimo tutorial, y bueno lo que les voy a mostrar ahora es un aplicacion que engloba todos los temas que no toque la vez pasada, como son condicionales, bucles, random, vectores y la funcion que oye cuando el mouse es presionado

Lo que van a ver es una tabla e ajedrez con una pelotita que choca en las paredes, y mientras va pasando por una casilla, la pinta de color plomo, la pelotita vuelve a una nueva posicion y la pantalla se reinicia si presionas el mouse, primero el codigo bien explicado:

int x,y;
int pasoX,pasoY;
float[][] ajedrez = new float[8][8];//matriz de la tabla de ajedrez
void setup(){
 size(200,200);
 smooth();//se utiliza para que el circulo se vean los bordes perfectos (anti-aliased)
 x = int(random(width));//random del ancho de la pantalla - 200
 y = int(random(height));//del largo
 pasoX = 2;
 pasoY = 4;
 for(int j=0 ; j<8 ; j++){
 for(int i=0 ; i<8 ; i++){
 if( (i+j) % 2 == 0 ){ //si la suma de la fila y la columna es par entonces pinta de negro
 ajedrez[j][i]=0;
 }else{
 ajedrez[j][i]=255;
 }
 }
 }
}
void draw(){
 for(int j=0 ; j<8 ; j++){ // recorrido de la pantalla para pintarla
 for(int i=0 ; i<8 ; i++){
 fill( ajedrez[j][i] );
 rect( i * 25 , j * 25 , 25 , 25 );//hace el cuadrado
 }
 }
 fill( 150 );
 ellipse(x,y,10,10);
 x += pasoX; //movimiento horizontal
 if( x > width || x < 0 ){ //bordes horizontales
 pasoX *= -1; //cambia de dirección horizontal
 }
 y += pasoY; //movimiento vertical
 if( y > height || y < 0 ){ //bordes verticales
 pasoY *= -1; //cambia de dirección vertical
 }
 for(int jb=0 ; jb<8 ; jb++){
 for(int ib=0 ; ib<8 ; ib++){
 if(dist( ib * 25 , jb * 25 , x , y ) < 10 ){ //dist -> calcula la distancia entre 2 puntos
 ajedrez[jb][ib] = int(random(140,150)); //random entre 140 y 150 (plomo)
 fill( ajedrez[jb][ib] );
 rect( ib * 25 , jb * 25 , 25 , 25 );
 }
 }
 }
}
void mousePressed(){
 setup(); // si presionas el mouse se reinicia
}

Listo con eso la pantalla quedaria asi:

Dibujo

Ahora la manipulacion de fotos es otro tema, por ejemplo voy a hacer un programa que suba una foto y la distorsione por donde pase el mouse

la foto que voy a poner es una foto que tome durante el concierto que salio asquerosa, para algo debia servir:

Imagen

y ahora el codigo que utilizo para que cuando paso el mose, se distorsione la imagen:

PImage imagen;  // para cargar imagenes
void setup(){
 size(240,320);   
 imagen = loadImage("Imagen.jpg"); //carga una imagen
 background(0);  
 image(imagen, 0, 0);  
}
void draw(){
 for(int x=0 ; x<width ; x++){  //recorre horizontalmente toda la imagen
 for(int y=0 ; y<height ; y++){  //recorre verticalmente toda la imagen
 color ese;  //variable del tipo color
 ese = imagen.get( x , y ); //vuelve a enfocar la foto cogiendo el color de el pixel de la foto original
 set( x , y , ese ); //imprime el color del pixel tomado
 }
 }
 float des = 15;  //el desenfoque
 for(int x=mouseX-30 ; x<30+mouseX ; x++){  //recorre horizontalmente hasta 60
 for(int y=mouseY-40 ; y<40+mouseY ; y++){  //recorre verticalmente hasta 80
 color este;
 este = imagen.get( x+int( random(-des,des) ) , y+int( random(-des,des) ) ); //toma el color de un pixel con un nivel de desenfoque
 set( x , y , este );
 }
 }
}

Acuerdense de que para poder agregar una imagen se van al menu ’sketch’Y luego le dan’ add file’ eligen la imagen y  listo con eso ya saben manejo de imagenes, bucles y demas, el resto uds averiguenlo por si mismos, pero les recomiendo este lenguaje por lo facil y simple que es, lo aprendes en una y haces un monton de tonterias con solo un poco de imaginacion, bueno les dejo la imagen de como queda al final, nos vemos, bye

Dibujo

pd-> les dejo unos links que me resultaron de inmensa ayuda para aprender, el primero es lo basico en español, y si les gusto y quieren aprender mucho mas, les recomiendo este enlace en ingles

6 Mayo 2009

Processing 1.0

Archivado en: Processing — Etiquetas:, — Julio Cesar Cachay Pérez @ 4:15 am

Despues de muchos(demasiados) dias actualizo mi blog, despues de mi super viaje a argentina(todo lo que hace radiohead :P ), por donde estuve mes y medio – fotito con mi primo ricardo antes de que comienze el concierto ^_^:

imagen002

(io soy el de lentes)

Y obviamente sin chances de escribir nada, regreso con un nuevo lenguaje desarrollado a partir de java que esta desarrollado para ser usado en vez de flash, processing 1.0.3 (su version mas actual hasta hoy) la verdad es que tiene muy buenas criticas y ya esta siendo utilizado en varias universidades, ya que java t permite hacer mas cosas que flash, o eso dicen…

Primero se lo bajan de la pagina de progressive donde dice download.

Ahora voy a comenzar mostrandoles primero como se dibuja, el codigo explica para que sirve cada funcion

size(300,300); //tamaño de la ventana
background(255); //pinta el fondo (blanco)

//punto
set(75,75,0); //pixel(punto) negro (x,y,color)
strokeWeight(4);//ancho de linea
//linea
line(10,20,130,140);//(x,y(de un lado),x,y(del otro))
//triangulo
triangle(10,110,80,20,130,130);//(x1,y1,x2,y2,x3,y3) de cada punto
//elipse
ellipseMode(CENTER); //(valor por defecto)
ellipse(70,80,130,80); //(x1,y1(del centro),x2,y2(ancho y alto))
ellipseMode(CORNER);
ellipse(70,80,130,80); //(x1,y1(del punto superior izquierdo del rectángulo),x2,y2(ancho y alto))
ellipseMode(CORNERS);
ellipse(70,80,130,80); //(x1,y1(un punto),x2,y2(el otro punto al extremo))
//cuadrado-rectangulo
rectMode(CORNER); //modo en que se interpretarán los parámetros en rect()-por defecto
rect(10,10,120,80); //(x1,y1(punto superior izquierdo),x2,y2(ancho y alto))
rectMode(CENTER);
rect(10,10,120,80); //(x1,y1(punto central),x2,y2(ancho y alto))
rectMode(CORNERS);
rect(10,10,120,80); //(x1,y1(punto central),x2,y2(ancho y alto))
//cuadrado-sin forma
quad(20,10,130,30,110,115,40,140); //(x1,y1(primer punto),x2,y2(segundo punto),x3,y3(tercer punto),x4,y4(cuarto punto))
//curva
bezier(20,10,40,140,120,30,110,115); //(x1,y1(un extremo),x2,y2(punto de salida),x3,y3(punto de llegada),x4,y4(otro extremo))
//arco
ellipseMode(CENTER); //los parametros de ellipse funcionan para arc;
arc(80,70,120,80,PI/2,0); //(x1,y1(centro),x2,y2(ancho y alto),rad1,rad2(punto de inicio y final))

Hasta aca hemos hecho algunos dibujos que quedara asi :

dibujo

Recuerden que para ejecutar deben hacer click en el boton con forma de play

Al igual que java, tiene una serie de variables y operaciones disponibles para nosotros, el codigo que sigue les mostrara un poco de esto

int Var; //entero
Var = 26;
println(Var); //imprime en la pantalla negra

float reales;//flotante para decimales(reales)
reales = 26.99;
println(reales);// 

//las operaciones son las mismas que podemos hacer en java con estos tipos de variables
//division de enteros devuelve enteros aun si la respuesta es en real

char letra;//almacena un dato alfanumerico
letra = 'j';
println(letra);// imprime una j

String oracion;//cadena de caracteres
oracion="julio c";
println(oracion);

boolean verdad;//datos booleanos
verdad = true;
println(verdad);

color fondo;//colores que se definen
fondo = 0;
background(fondo); //pinta la ventana de negro

Hasta ahora solo hemos probado lo basico de progressive, y ahora veremos la gracia de esto, empezaremos a utilizar las funciones setup() y draw(), la funcion setup() se ejecuta una sola vez en el programa, mientras que todas las instrucciones bajo la funcion draw() se ejecutan 30 veces en 1 segundo indefinidamente, veamos un ejemplo.

int c;
void setup(){
 c = 10;
 size(100,100);
}
void draw(){
 background(200);
 c = (c+1) % 100;
 rect(c,30,15,15);
}

Veran en su pantalla un cuadrado que se mueve como estedibujo1

Existe tambien unas funciones que se llaman mouseX y mouseY estas representan las coordenadas x y del mouse, un ejemplo:

int x = 50;
int y = 50;
void setup(){
 size(300,300);
}
void draw(){
 background(100); //si borran esta linea los cuadrados no se borran
 x=mouseX-20;
 y=mouseY-20;
 rect(x,y,60,60);
}

Quedaria de la sgte forma:

dibujo2

y si borramos los //

dibujo21

A partir de aca todo lo que necesitan es imaginacion, les voy a dar algunas funciones mas que pueden necesitar a lo largo del desarrollo de aplicaciones en este lenguaje:

size(200,100);
stroke(255,0,0);//te permite cambiar el color del dibujo actual
point(50,50);//función de punto(x,y), fijará el pixel en 50,50 al color del lienzo actual (rojo)
fill(#CC6600);//es lo que hace que el sgte triangulo sea verde, stroke hace que lo rodee una linea roja
triangle(12,50, 120,15, 125,60);
noFill( );//no hace ningun llenado
ellipse(160,30,60,60);
curve(84, 91, 68, 19, 21, 17, 32, 100);//otra forma de hacer curvas, igual a bezier pero los parámetros de en medio establecen los puntos para definir la forma de la curva
bezier(84, 91, 68, 19, 21, 17, 32, 100);//Los parámetros de en medio otorgan el contexto para definir la forma de la curva
noStroke();//deshabilita los bordes y no son dibujados

Hasta aqui todo lo basico de progressive, despues veremos un poco mas, como figuras, framerate, condicionales, bucles, etc

c’ ya

18 Febrero 2009

Pulpcore y Sax, usando XML

Archivado en: Pulpcore — Etiquetas:, , , , — Julio Cesar Cachay Pérez @ 1:41 am

Bueno estuve revisando alguna forma de leer XML en java y me di con 2 formas de hacerlo de forma nativa y algunas mas usando parsers, solo hablare de los de forma nativa que son DOM y SAX... bueno tampoco es que vaya a hablar mucho de ellos, solo les dire que la ventaja de SAX es el menor consumo de memoria que DOM pero como desventaja es su dificultad.

Tambien revise algunos parsers pero trato de mantener al minimo el tamaño de los archivos, y estar bajando (y anexando) Xerces o JDom no me convencio del todo, ademas no es que vaya a necesitar tanto de la funcionalidad de los parsers cuando solo voy a leer o escribir XML simples, como los gringos… “keep it simple” aunque SAX no lo es tanto…

Ahora porque digo que SAX es mas rapido, una buena lectura es la de esta pagina, en la parte que dice SAX vs DOM, aunque si googlean un poco pueden encontrar mas informacion. Se fijaran que usan Xerces como parser, pero eso es porque, y esto no lo tengo por seguro, usaban el jdk 1.3, ya que desde la version 1.4 se incluye un parser

Bueno tambien queria indicarles que se puede usar php ademas de java para la escritura y lectura de los archivos XML pero eso lo veremos en otro post (otro mas a la lista “prometi y no cumplo” XD )

Ahora si a lo que vamos, primero decirles que los applets tiene una seguridad propia de ellas que no permiten escribir XML y solo leer archivos desde tu propio servidor, entonces esto quiere decir que si uds corren algun applet sin usar un servidor este simplemente no leera su xml, es por eso que necesitamos primero hacer nuestro servidor y la manera mas facil es o usando apache, o el servidor tomcat de netbeans, io la verdad es que no instale tomcat con netbeans y por eso me baje el servidor apache, concretamente EasyPHP 3.0, porque tambien quiero hacer la prueba con php despues y con un par de “siguientes” tenemos corriendo el apache en 1 seg. Descarguenlo, instalenlo y en la carpeta www (C:\Archivos de programa\EasyPHP 3.0\www, si lo instalaron en esa ruta), copian toda la carpeta build generado en netbeans, en su navegador colocan 127.0.0.1 y veran correr a su applet

Sax lee los archivos XML de forma estructurada a diferencia de Dom que crea objetos, esto hace que Dom consuma mas memoria, es por eso que elegi Sax, lo que no he visto en internet son applets que usen Sax, bueno con pulcore veremos como hacer esto ahora.

Pero y ¿para qué usar XML? bueno imaginense que tenemos un juego y lo queremos tener en varios idiomas, entonces ¿no seria mejor tener toda la traduccion aparte en otro archivo y asi poder agregar varios lenguajes sin ninguna modificacion en el codigo? … yo tambien pensaba lo mismo ^^.

Ok a lo que vamos primero el XML

<?xml version="1.0" encoding="UTF-8"?>

<!--
    Document   : juego.xml
    Created on : 18 de febrero de 2009, 08:24 PM
    Author     : Julio Cachay
    Description:
        Datos del juego en español
-->

<juego>
    <nombre>Pio Pio</nombre>
    <descripcion>Juego arcade</descripcion>
<personaje-principal>
        <nombre>Pollito</nombre>
        <habilidad>Comer maiz</habilidad>
    </personaje-principal>
</juego>

Ahora el manejador SAX, cabe decirles que para hacer estas clases me base en el ejemplo de lector XML que contienen elementos anidados de Alberto Molpeceres. solo que no uso el parser de xerces sino el que te viene en el jdk

/**
 *
 * @author Julio Cachay
 */
import java.util.Vector;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

public class ManejadorSax {

    private Vector instancias = new Vector();
    private JuegoXMLHandler manejador;

    public ManejadorSax() {
        procesarFichero();
    }

    private void procesarFichero() {
        try {
            XMLReader reader = XMLReaderFactory.createXMLReader();
            manejador = new JuegoXMLHandler(reader, instancias);
            reader.setContentHandler(getManejador());
            reader.parse(new InputSource("http://127.0.0.1/juego.xml"));
            System.out.println("Juego:");
            System.out.println(getManejador().getActual().toString());
            System.out.println("Personaje Principal:");
            System.out.println(getManejador().getHandlerPersonaje().getPersonaje().toString());
        } catch (Exception e) {
            System.out.println("Error al procesar el fichero del juego: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * @return the manejador
     */
    public JuegoXMLHandler getManejador() {
        return manejador;
    }
}

Ahora los handler, primero el juego

/**
 *
 * @author Julio Cachay
 */
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.Attributes;
import java.util.Vector;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

public class JuegoXMLHandler extends DefaultHandler {
    /* Esto no es nuevo */
    //vector de instancias
    private Vector instancias;
    //"Juego" que se esta procesando
    private Juego actual;
    //valor contenido entre las etiquetas de un elemento
    private String valor;
    /* Esto si es nuevo */
    //Como queremos pasar el control del proceso de un
    //Handler a otro, necesitamos tener el parser para
    //asignarle el Handler que necesite en cada instante.
    private XMLReader parser;
    //Este es el Handler que procesara los personajes que
    //contenga el documento
    private PersonajeXMLHandler handlerPersonaje;

    public JuegoXMLHandler(XMLReader parser, Vector v) {
        this.parser = parser;
        this.instancias = v;
    }

    public void startElement(String namespaceURI, String localName, String qName,
            Attributes attr) throws SAXException {
        //comprobamos si empezamos un elemento "juego"
        if (localName.equals("juego")) {
        //creamos la nueva instancia de Juego
            actual = new Juego();
            //y la añadimos al Vector que las almacena
            instancias.addElement(getActual());
        } else if (localName.equals("personaje-principal")) {
            //creamos una instancia de Personaje
            Personaje principal = new Personaje();
            //se la asignamos al juego actual como principal
            getActual().setPrincipal(principal);
            /*
            y pasamos el control al Handler de personaje principal
            le tenemos que pasar el parser, para que recoga
            los datos del fichero, este Handler para que luego
            nos devuelva el control, y el personaje donde meter
            los datos que procese.
             */
            handlerPersonaje = new PersonajeXMLHandler(parser, this, principal);
            parser.setContentHandler(getHandlerPersonaje());
        }
    }

    public void endElement(String namespaceURI, String localName, String rawName)
            throws SAXException {
        /*
        miramos de que elemento se trata y asignamos los atributos
        correspondientes al "Juego" actual.
         */
        if (localName.equals("nombre")) {
            getActual().setNombre(valor);
        } else if (localName.equals("descripcion")) {
            getActual().setDescripcion(valor);
        }
        valor = null;
    }
    /*
    Los parametros que recibe es la localizacion de los carateres del elemento.
     */

    public void characters(char[] ch, int start, int end) throws SAXException {
    //creamos un String con los caracteres del elemento y le quitamos
    //los espacios en blanco que pueda tener en los extremos.
        valor = new String(ch, start, end);
        valor = valor.trim();
    }

    /**
     * @return the handlerPersonaje
     */
    public PersonajeXMLHandler getHandlerPersonaje() {
        return handlerPersonaje;
    }

    /**
     * @return the actual
     */
    public Juego getActual() {
        return actual;
    }
}

Ahora el personaje

/**
 *
 * @author Julio Cachay
 */
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

public class PersonajeXMLHandler extends DefaultHandler {
    //valor contenido entre las etiquetas de un elemento
    private String valor;
    //El parser, para luego devolver el control al
    //Handler de juego.
    private XMLReader parser;
    //El Handler al que queremos volver
    private JuegoXMLHandler handlerJuego;
    //EL personaje donde meter los datos que leamos.
    private Personaje personaje;

    public PersonajeXMLHandler(XMLReader parser, JuegoXMLHandler handler,
            Personaje personaje) {
        this.parser = parser;
        this.handlerJuego = handler;
        this.personaje = personaje;
    }

    public void endElement(String namespaceURI, String localName, String rawName)
            throws SAXException {
        /*
        miramos de que elemento se trata y asignamos los atributos
        correspondientes a el "Personaje" actual o devolvemos el control
        al Handler de juego.
         */
        if (localName.equals("nombre")) {
            getPersonaje().setNombre(valor);
        } else if (localName.equals("habilidad")) {
            getPersonaje().setHabilidad(valor);
        } //si hemos llegado al final de la etiqueta
        else if (localName.equals("persona-contacto")) {
            parser.setContentHandler(handlerJuego);
        }
        valor = null;
    }
    /*
    Los parametros que recibe es la localizacion de los carateres del elemento.
     */

    public void characters(char[] ch, int start, int end) throws SAXException {
    //creamos un String con los caracteres del elemento y le quitamos
    //los espacios en blanco que pueda tener en los extremos.
        valor = new String(ch, start, end);
        valor = valor.trim();
    }

    /**
     * @return the personaje
     */
    public Personaje getPersonaje() {
        return personaje;
    }
}

Es hora de crear los objetos donde se almacenara la informacion correspondiente, primero Juego

/**
 *
 * @author Julio Cachay
 */
public class Juego {

    private String nombre;
    private String descripcion;
    private Personaje principal;

    public Juego() {
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public void setDescripcion(String descripcion) {
        this.descripcion = descripcion;
    }

    public void setPrincipal(Personaje principal) {
        this.principal = principal;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("   nombre: " + nombre);
        sb.append("   descripcion: " + descripcion);
        return sb.toString();
    }
}

Ahora personaje principal

/**
 *
 * @author Julio Cachay
 */
public class Personaje {

    private String nombre;
    private String habilidad;

    public Personaje() {
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public void setHabilidad(String habilidad) {
        this.habilidad = habilidad;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("   nombre: " + nombre);
        sb.append("   habilidad: " + habilidad);
        return sb.toString();
    }
}

Con todo esto somos capaces de traer el xml de la ruta 127.0.0.1 que te da apache, recuerden subir el xml a la carpeta www

Es hora de mostrarlo al publico

import pulpcore.scene.Scene2D;
import pulpcore.sprite.FilledSprite;
import pulpcore.sprite.Label;
import static pulpcore.image.Colors.*;

/**
 *
 * @author Julio Cachay
 */
public class Escena extends Scene2D {

    Label juego;
    Label personaje;

    @Override
    public void load() {
        ManejadorSax ms = new ManejadorSax();
        add(new FilledSprite(rgb(185, 209, 255)));
        juego = new Label("Juego: " + ms.getManejador().getActual().toString(), 20, 120);
        personaje = new Label("Personaje Principal: " + ms.getManejador().getHandlerPersonaje().getPersonaje().toString(), 20, 320);
        add(juego);
        add(personaje);
    }
}

Listo! ya terminamos todo, el resultado se vera asi

dibujo

Recuerden que pueden ver como quedo y bajarse el codigo desde mi pagina aqui

13 Febrero 2009

Pulpcore, alucard y su mapa

Archivado en: Pulpcore — Etiquetas:, , , , — Julio Cesar Cachay Pérez @ 11:46 pm

Bueno hasta ahora teniamos la animacion de Alucard y como crear un mapa es momento de fusionarlos y crear un juego de estilo plataforma, de los que no he visto en pulcore todavia, para esto le voy dar control a alucard mediante las flechas. Primero usaremos la clase mapa anteriormente creada


import pulpcore.Stage;
import pulpcore.animation.Fixed;
import pulpcore.image.CoreGraphics;
import pulpcore.image.CoreImage;
import pulpcore.sprite.Sprite;

/**
 *
 * @author Julio Cachay
 */
public class mapa extends Sprite {

    private CoreImage[][] MapaTile;
    private int TileWidth;
    private int TileHeight;
    private int numTilesLargo;
    private int numTilesFilas;
    public final Fixed vistaX = new Fixed(this);
    public final Fixed vistaY = new Fixed(this);

    public mapa(CoreImage[][] MapaTile, int Width, int Height) {
        //lo colocamos a la izquierda y en la parte de abajo
        super(0, Stage.getHeight() - Height, Stage.getWidth(), Stage.getHeight());
        this.MapaTile = MapaTile;
        this.TileWidth = Width;
        this.TileHeight = Height;
        numTilesLargo = MapaTile.length;
        numTilesFilas = MapaTile[0].length;
        // para manejo de posiciones exactas en píxeles.
        pixelSnapping.set(true);
    }

    //El largo del mapa
    public int getMapWidth() {
        return TileWidth * numTilesLargo;
    }

    //El alto del mapa
    public int getMapHeight() {
        return TileHeight * numTilesFilas;
    }

    //Altura de la tierra
    public int tierraFirme(){
        return Stage.getHeight() - TileHeight;
    }

    //se mueve?
    public boolean isScrolling() {
        return vistaX.isAnimating() || vistaY.isAnimating();
    }

    @Override
    public void update(int elapsedTime) {
        super.update(elapsedTime);
        vistaX.update(elapsedTime);
        vistaY.update(elapsedTime);
    }

    //sobreescribimos la funcion drawSprite para dibujar el mapa
    @Override
    protected void drawSprite(CoreGraphics g) {
        int y = vistaY.getAsIntFloor();
        for (int j = 0; j < numTilesFilas; j++) {
            int x = vistaX.getAsIntFloor();
            for (int i = 0; i < numTilesLargo; i++) {
                g.drawImage(MapaTile[i][j], x, y);
                x += TileWidth;
            }
            y += TileHeight;
        }
    }
}

Ya tenemos listo el mapa ahora el escenario

import pulpcore.Input;
import pulpcore.Stage;
import pulpcore.animation.Easing;
import pulpcore.image.BlendMode;
import pulpcore.image.CoreImage;
import pulpcore.scene.Scene2D;
import pulpcore.sprite.FilledSprite;
import pulpcore.sprite.Group;
import pulpcore.sprite.ImageSprite;
import static pulpcore.image.Colors.*;

/**
 *
 * @author Julio Cachay
 */
public class mapaAnimado extends Scene2D {

    CoreImage AlucardDer;
    CoreImage AlucardIzq;
    CoreImage AlucardPDer;
    CoreImage AlucardPIzq;
    ImageSprite jugador;
    Group grupo;
    boolean cargo = false;
    int i;
    int y;
    double velocidadJugador = 5;
// Nombre de las fotos
    String bloques[] = {"t01.png", "t02.png", "t03.png", "t04.png", "t05.png", "t06.png", "t07.png",
        "t08.png", "t09.png", "t10.png", "t11.png", "t12.png", "t13.png", "t14.png", "t15.png", "t16.png",
        "t17.png", "t18.png", "t19.png", "t20.png"};
    //este sera la forma de llenar, es la relacion de imagenes
    String mapa[] = {"t01t02t03t04t05t06t07t08t09t10t11t12t13t14t15t16t17t18t19t20" +
        "t01t02t03t04t05t06t07t08t09t10t11t12t13t14t15t16t17t18t19t20"};
    mapa mapaTile;

    @Override
    public void load() {
        // agregamos un cielo azul
        add(new FilledSprite(rgb(185, 209, 255)));
        // creamos el mapa
        mapaTile = crearMapa(bloques, mapa, 24, 72);
        //adherimos el mapa
        add(mapaTile);
        // agregamos a Alucard
        AlucardPDer = CoreImage.load("res/alucardfrenada.png");
        AlucardPIzq = AlucardPDer.mirror();
        AlucardDer = CoreImage.load("res/alucard.png");
        AlucardIzq = AlucardDer.mirror();
        jugador = new ImageSprite(AlucardDer, Stage.getWidth() / 2, mapaTile.tierraFirme());
        //para que el jugador se conviene bien con el mapa, lean las tecnicas RGB que se usan en el API
        jugador.setBlendMode(BlendMode.SrcOver());
        grupo = new Group();
        grupo.pixelSnapping.set(true);
        grupo.add(jugador);
        grupo.x.bindTo(mapaTile.vistaX);
        grupo.y.bindTo(mapaTile.vistaY);

        add(grupo);
    }

    @Override
    public void update(int elapsedTime) {
//Presionan el boton izquierdo
        if (Input.isDown(Input.KEY_LEFT)) {
            if (velocidadJugador > 0) {
                velocidadJugador = velocidadJugador * -1;
            }
            if (!cargo) {
                cargar();
                cargo = true;
            }
            jugador.setImage(AlucardIzq);
        }
//Presionan el boton derecho
        if (Input.isDown(Input.KEY_RIGHT)) {
            if (velocidadJugador < 0) {
                velocidadJugador = Math.abs(velocidadJugador);
            }
            if (!cargo) {
                cargar();
                cargo = true;
            }
            jugador.setImage(AlucardDer);
        }
// no presionan nada
        if (!Input.isDown(Input.KEY_LEFT) && !Input.isDown(Input.KEY_RIGHT)) {
            if (velocidadJugador > 0) {
                jugador.setImage(AlucardPDer);
            } else {
                jugador.setImage(AlucardPIzq);
            }
            cargo = false;
        } else {
            double x = jugador.x.get() + velocidadJugador;
            jugador.x.set(x);
            setDirtyRectanglesEnabled(!mapaTile.isScrolling());
            double metaX = mapaTile.vistaX.get() + velocidadJugador * -1;
            mapaTile.vistaX.animateTo(metaX, Math.abs((int) velocidadJugador), Easing.REGULAR_OUT);
        }
    }

    void cargar() {
        AlucardPDer = CoreImage.load("res/alucardfrenada.png");
        AlucardPIzq = AlucardPDer.mirror();
    }

    private mapa crearMapa(String[] bloques, String[] mapa, int Tilewidth, int Tileheight) {
        //cargar las imagenes de bloque
        CoreImage[] ImagenesBloque = new CoreImage[bloques.length];
        int i = 0;
        while (i < ImagenesBloque.length) {
            ImagenesBloque[i] = CoreImage.load("res/" + bloques[i]);
            i++;
        }
        //Creamos un mapa con los bloques
        i = 0;
        int y = 0, m = 0;
        int filMapa = mapa[0].length();
        int colMapa = mapa.length;
        CoreImage[][] mapaTile = new CoreImage[filMapa / 3][colMapa];
        while (i < filMapa - 3) {
            y = 0;
            while (y < colMapa) {
                //Comparamos las primeras letras del mapa con las del bloque
                // ejem. t01 == t01, si lo es la imagen cargada se almacena en el mapa
                String str = mapa[y].substring(i, i + 3);
                int k = 0;
                int index = 0;
                while (k < bloques.length) {
                    if (bloques[k].substring(0, 3).contentEquals(str)) {
                        index = k;
                        break;
                    }
                    k++;
                }
                mapaTile[m][y] = ImagenesBloque[index];
                y++;
            }
            m++;
            i = i + 3;
        }
        return new mapa(mapaTile, Tilewidth, Tileheight);
    }
}

Listo, terminado y finito, con eso solo hacer volar un poco la imaginacion, luego les hablare mas profundamente de colisiones, el codigo y para ver como quedo esta aqui

alucard

Saludos

5 Febrero 2009

Haciendo un mapa

Archivado en: Pulpcore — Etiquetas:, , , , — Julio Cesar Cachay Pérez @ 7:23 pm

Ya que animamos a alucard es hora de hacer un terrenito donde pueda caminar para eso utilizaremos una imagen que encontre en la web y que la rompi en varios pedacitos con gimp

Ahora renombramos las figuras para que queden con nombre de tamaño 6, ejem: t01.png, t11.png, etc

t41 = t04

Muy bien ahora el codigo de la clase principal

import pulpcore.image.CoreImage;
import pulpcore.scene.Scene2D;
import pulpcore.sprite.FilledSprite;
import static pulpcore.image.Colors.*;

/**
 *
 * @author Julio Cachay
 */
public class mapaBloque extends Scene2D {
// Nombre de las fotos
    String bloques[] = {"t01.png", "t02.png", "t03.png", "t04.png", "t05.png", "t06.png", "t07.png",
        "t08.png", "t09.png", "t10.png", "t11.png", "t12.png", "t13.png", "t14.png", "t15.png", "t16.png",
        "t17.png", "t18.png", "t19.png", "t20.png"};
    //este sera la forma de llenar, es la relacion de imagenes
    String mapa[] = {"t01t02t03t04t05t06t07t08t09t10t11t12t13t14t15t16t17t18t19t20" +
        "t01t02t03t04t05t06t07t08t09t10t11t12t13t14t15t16t17t18t19t20"};
    mapa mapaTile;

    @Override
    public void load() {
        // agregamos un cielo azul
        add(new FilledSprite(rgb(185, 209, 255)));
        // creamos el mapa
        mapaTile = crearMapa(bloques, mapa, 24, 72);
        //adherimos el mapa
        add(mapaTile);

    }

    private mapa crearMapa(String[] bloques, String[] mapa, int Tilewidth, int Tileheight) {
        //cargar las imagenes de bloque
        CoreImage[] ImagenesBloque = new CoreImage[bloques.length];
        int i = 0;
        while (i < ImagenesBloque.length) {
            ImagenesBloque[i] = CoreImage.load("res/" + bloques[i]);
            i++;
        }
        //Creamos un mapa con los bloques
        i = 0;
        int y = 0, m = 0;
        int filMapa = mapa[0].length();
        int colMapa = mapa.length;
        CoreImage[][] mapaTile = new CoreImage[filMapa / 3][colMapa];
        while (i < filMapa - 3) {
            y = 0;
            while (y < colMapa) {
                //Comparamos las primeras letras del mapa con las del bloque
                // ejem. t01 == t01, si lo es la imagen cargada se almacena en el mapa
                String str = mapa[y].substring(i, i + 3);
                int k = 0;
                int index = 0;
                while (k < bloques.length) {
                    if (bloques[k].substring(0, 3).contentEquals(str)) {
                        index = k;
                        break;
                    }
                    k++;
                }
                mapaTile[m][y] = ImagenesBloque[index];
                y++;
            }
            m++;
            i = i + 3;
        }
        return new mapa(mapaTile, Tilewidth, Tileheight);
    }

    @Override
    public void update(int elapTime) {
    }
}

Ahora el codigo del mapa

import pulpcore.Stage;
import pulpcore.animation.Fixed;
import pulpcore.image.CoreGraphics;
import pulpcore.image.CoreImage;
import pulpcore.sprite.Sprite;

/**
 *
 * @author Julio Cachay
 */
public class mapa extends Sprite {

    private CoreImage[][] MapaTile;
    private int TileWidth;
    private int TileHeight;
    private int numTilesLargo;
    private int numTilesFilas;
    public final Fixed vistaX = new Fixed(this);
    public final Fixed vistaY = new Fixed(this);

    public mapa(CoreImage[][] MapaTile, int Width, int Height) {
        //lo colocamos a la izquierda y en la parte de abajo
        super(0, Stage.getHeight() - Height, Stage.getWidth(), Stage.getHeight());
        this.MapaTile = MapaTile;
        this.TileWidth = Width;
        this.TileHeight = Height;
        numTilesLargo = MapaTile.length;
        numTilesFilas = MapaTile[0].length;
        // para manejo de posiciones exactas en píxeles.
        pixelSnapping.set(true);
    }

    //El largo del mapa
    public int getMapWidth() {
        return TileWidth * numTilesLargo;
    }

    //El alto del mapa
    public int getMapHeight() {
        return TileHeight * numTilesFilas;
    }

    //se mueve?
    public boolean isScrolling() {
        return vistaX.isAnimating() || vistaY.isAnimating();
    }

    @Override
    public void update(int elapsedTime) {
        super.update(elapsedTime);
        vistaX.update(elapsedTime);
        vistaY.update(elapsedTime);
    }

    //sobreescribimos la funcion drawSprite para dibujar el mapa
    @Override
    protected void drawSprite(CoreGraphics g) {
        int y = vistaY.getAsIntFloor();
        for (int j = 0; j < numTilesFilas; j++) {
            int x = vistaX.getAsIntFloor();
            for (int i = 0; i < numTilesLargo; i++) {
                g.drawImage(MapaTile[i][j], x, y);
                x += TileWidth;
            }
            y += TileHeight;
        }
    }
}

Con este codigo tendremos esto:

mapa

le baje la calidad para que pese menos, pueden ver como quedo y bajar el codigo aqui

Nos vemos

Entradas más antiguas »

Blog de WordPress.com.