Nossos formulários podem conter campos tipo date, tais como a data de nascimento. É interessante que guardemos essa informação no banco de dados com o tipo correto. Isso nos permite fazer operações de data com essa data guardada, por exemplo, buscar os usuários que possuem certa idade.
Crie a tabela no banco:
CREATE TABLE `usuario`(
`id` int(11) NOT NULL AUTO_INCREMENT,
`nome` text NOT NULL,
`nascimento` date NOT NULL,
PRIMARY KEY (`id`)
)
Crie o formulário HTML:
Novo usuario:<br/>
<form action="gravar.php" method="post">
<input type="text" name="nome" /><br/>
<input type="text" name="nascimento" /> (dd/mm/aaaa)<br/>
<input type="submit" value="gravar" />
</form>
Perceba que a data a ser fornecida tem que seguir o padrão 'dd/mm/aaaa'
Crie o script gravar.php que guardará no banco (coloco o script de forma simplificada para não perder o foco do artigo, mas o ideal seria isolar o código que acessa o banco de dados em um objeto DAO)
<?php
//função que valida a data
function dataValida($dat) {
try {
$data = explode("/", $dat); // explode a string $dat em pedaços, usando / como referência
$d = $data[0];
$m = $data[1];
$y = $data[2];
// verifica se a data é válida!
// 1 = true (válida)
// 0 = false (inválida)
$res = checkdate($m, $d, $y);
if ($res == 1) {
return true;
} else {
return false;
}
} catch (Exception $exc) {
return false;
}
}
$furou = false;//controla a validação
if (trim($_REQUEST['nascimento']) == '' || !dataValida($_REQUEST['nascimento'])) {
$furou = true;
}
if (trim($_REQUEST['nome']) == '') {
$furou = true;
}
if($furou){
echo 'Todos os campos são obrigatórios! Verifique o formato da data dd/mm/aaaa';
//redirecione de volta para o formulário
}else{
//ok, pode gravar
$connection = mysql_connect('bancourl', 'usuario', 'senha');
$db = mysql_select_db($config->getDataBaseName(), $connection);
$sql = "insert into usuario(nome, nascimento) values ('".$_REQUEST['nome'])."', STR_TO_DATE('" . $_REQUEST['nascimento']) . "','%d/%m/%Y'))";
mysql_query($sql);
echo mysql_error();
mysql_close($connection);
}
?>
Observe que oriento o MySQL a usar o padrão 'dd/mm/aaaa' nesse trecho: '%d/%m/%Y'. Você pode alterar essa padrão por exemplo para dd-mm-aaaa usando: '%d-%m-%Y', mas lembre de alterar também a função em php onde fazemos a validação da data.
Para exibir a data cadastrada:
$connection = mysql_connect('bancourl', 'usuario', 'senha');
$db = mysql_select_db($config->getDataBaseName(), $connection);
$sql = "select nome, DATE_FORMAT(nascimento,'%d/%m/%Y') as nascimento from usuario";
$result = mysql_query($sql);
while ($row = mysql_fetch_array($result)) {
echo $row['nascimento'];// exibirá a data no formato dd/mm/aaaa
}
echo mysql_error();
mysql_close($connection);
Fica a dica.
Gustavo Marques.
sábado, 17 de novembro de 2012
Gerando senhas aleatórias com PHP
Um sistema que possua uma base de usuários com login e senha precisa fornecer mecanismos para recuperação de senha. Isso é importante porque o usuário pode esquecer sua senha. Assim é comum encontrarmos o link 'esqueci minha senha' nos sistemas que possuem login.
Ao clicar nesse link podemos gerar uma senha randômica e enviá-la por email ao usuário.
Essa solução tem várias implementações, segue uma maneira
function gerarNovaSenha(){
$letras = array(
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'x',
'z',
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9'
);
shuffle($letras);
$novasenha = '';
for ($i = 0; $i < 10; $i++) {//10 é o tamanho da nova senha, substitua conforme a necessidade
$novasenha = $novasenha . $letras[$i];
}
return $novasenha;
}
Poderá incluir ainda nesse array simbolos '#@*&-_=+' e também caracteres em maiúscula para diversificar ainda mais.
Gustavo Marques.
Ao clicar nesse link podemos gerar uma senha randômica e enviá-la por email ao usuário.
Essa solução tem várias implementações, segue uma maneira
function gerarNovaSenha(){
$letras = array(
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'x',
'z',
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9'
);
shuffle($letras);
$novasenha = '';
for ($i = 0; $i < 10; $i++) {//10 é o tamanho da nova senha, substitua conforme a necessidade
$novasenha = $novasenha . $letras[$i];
}
return $novasenha;
}
Poderá incluir ainda nesse array simbolos '#@*&-_=+' e também caracteres em maiúscula para diversificar ainda mais.
Gustavo Marques.
quarta-feira, 7 de novembro de 2012
CRUD no Banco de Dados com Java e JDBC parte 2 - Criando seu Servlet
No post anterior expliquei como criar o seu DAO, ou seja, a camada de sua aplicação que irá acessar o banco de dados.
Vamos agora criar o nosso Servlet que irá utilizar os serviços oferecidos pelo nosso DAO.
Servlet
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author User
*/
public class ListarProdutos extends HttpServlet {
/**
* Processes requests for both HTTP
* <code>GET</code> and
* <code>POST</code> methods.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//variável que controla para qual view rotear após a execução desse Servlet
String view = "";
//Vamos criar uma conexão com o banco de Dados para passar ao nosso Dao.
//É esse servlet que irá gerenciar a conexão
java.sql.Connection con = null;
try {
con = Conexao.fabricar();//padrão factory, classe descrita depois desse servlet.
con.setAutoCommit(false);//permitindo transações
ProdutoDao dao = new ProdutoDao(con);
List<Produto> produtos = dao.listarTodos();
con.commit();
//manda para a view
request.setAttribute("produtos",produtos);
view = "listagem.jsp";
} catch(Exception ex){
view = "erro.jsp";
try{
con.rollback();
}catch(Exception ex2){}
}finally {
try{
con.close();
}catch(Exception ex3){}
}
request.getRequestDispatcher(view).foward(request, response);
}
// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
/**
* Handles the HTTP
* <code>GET</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Handles the HTTP
* <code>POST</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Returns a short description of the servlet.
*
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}
Não esqueça de registrar seu Servlet no arquivo web.xml, logo abaixo da tag <web-app> inclua:
web.xml
<servlet>
<servlet-name>ListarProdutos</servlet-name>
<servlet-class>servlets.ListarProdutos</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ListarProdutos</servlet-name>
<url-pattern>/ListarProdutos</url-pattern>
</servlet-mapping>
Vamos agora criar o nosso Servlet que irá utilizar os serviços oferecidos pelo nosso DAO.
Servlet
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author User
*/
public class ListarProdutos extends HttpServlet {
/**
* Processes requests for both HTTP
* <code>GET</code> and
* <code>POST</code> methods.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//variável que controla para qual view rotear após a execução desse Servlet
String view = "";
//Vamos criar uma conexão com o banco de Dados para passar ao nosso Dao.
//É esse servlet que irá gerenciar a conexão
java.sql.Connection con = null;
try {
con = Conexao.fabricar();//padrão factory, classe descrita depois desse servlet.
con.setAutoCommit(false);//permitindo transações
ProdutoDao dao = new ProdutoDao(con);
List<Produto> produtos = dao.listarTodos();
con.commit();
//manda para a view
request.setAttribute("produtos",produtos);
view = "listagem.jsp";
} catch(Exception ex){
view = "erro.jsp";
try{
con.rollback();
}catch(Exception ex2){}
}finally {
try{
con.close();
}catch(Exception ex3){}
}
request.getRequestDispatcher(view).foward(request, response);
}
// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
/**
* Handles the HTTP
* <code>GET</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Handles the HTTP
* <code>POST</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Returns a short description of the servlet.
*
* @return a String containing servlet description
*/
@Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}
Não esqueça de registrar seu Servlet no arquivo web.xml, logo abaixo da tag <web-app> inclua:
web.xml
<servlet>
<servlet-name>ListarProdutos</servlet-name>
<servlet-class>servlets.ListarProdutos</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ListarProdutos</servlet-name>
<url-pattern>/ListarProdutos</url-pattern>
</servlet-mapping>
Agora a classe Fábrica de Conexões:
Conexao.java
Conexao.java
public class Conexao {
public static Connection fabricar() throws Exception {
Class.forName("com.mysql.jdbc.Driver").newInstance();
return DriverManager.getConnection("jdbc:mysql://localhost/banco" ,"usuario" ,"senha" );
}
}
No próximo post implementaremos a View com JSP e JSTL.
Gustavo Marques.
segunda-feira, 5 de novembro de 2012
Fazendo download de arquivos pelo navegador com java a partir de sua aplicação web
Muitas são as situações que exigem a implementação de download de arquivo. Podemos gerar um relatorio em pdf dinamicamente e disponibiliza-lo para download pelo navegador, ou baixar imagens, arquivos zip etc. Porém as vezes não podemos simplesmente passar o caminho do arquivo via url para o usuario digitar na barra de endereços. Um exemplo disso são .war magros. Os usuários vão fazendo uploads mas os arquivos não ficam em uma pasta do war, mas sim em uma pasta do servidor fora do contexto da aplicação, por exemplo C:\arquivos. Os usuarios do sistema web não podem acessar essa pasta do servidor pelo browser, pois está fora do contexto da aplicação.
Assim devemos criar um objeto java.io.File com a localizaçao do arquivo que queremos servir e escrevê-lo no HttpServletResponse.
Vamos ao código:
File arquivo = new File("C:\arquivos\relatorio.pdf");
//tipo de arquivo
response.setContentType("application/pdf");
//nome do arquivo a ser exibido na caixa de download do browser
response.setHeader("Content-Disposition", "attachment; filename=" + arquivo.getName()+ ";");
//manda os bytes do arquivo pelo response
URL url = arquivo.toURI().toURL();
BufferedInputStream leitor = new BufferedInputStream(url.openStream(), 4 * 1024);
OutputStream escritor = response.getOutputStream();
byte[] buffer = new byte[4 * 1024];
int size = 0;
while ((size = leitor.read(buffer, 0, buffer.length)) != -1) {
escritor.write(buffer, 0, size);
}
escritor.close();
leitor.close();
Isso fará com que o browser do usuário exiba a caixa de download.
Se você não souber antecipadamente qual o tipo de arquivo que irá entregar, poderá definir em tempo de execução verificando a extensão do arquivo:
//pega a extensão do arquivo
String[] partes = arquivo.getNome().split("\\.");
int ultimaParte = partes.length - 1;
String extensao = partes[ultimaParte];
//seta o content type segundo a extensão
if (extensao.equals("doc")) {
response.setContentType("application/msword");
}
if (extensao.equals("pdf")) {
response.setContentType("application/pdf");
}
if (extensao.equals("pdf")) {
response.setContentType("application/pdf");
}
if (extensao.equals("xls")) {
response.setContentType("application/vnd.ms-excel");
}
if (extensao.equals("ppt")) {
response.setContentType("application/vnd.ms-powerpoint");
}
if (extensao.equals("gzip")) {
response.setContentType("application/gzip");
}
if (extensao.equals("zip")) {
response.setContentType("application/zip");
}
if (extensao.equals("au") || extensao.equals("snd")) {
response.setContentType("audio/basic");
}
if (extensao.equals("midi")) {
response.setContentType("audio/midi");
}
if (extensao.equals("aiff")) {
response.setContentType("audio/x-aiff");
}
if (extensao.equals("wav")) {
response.setContentType("audio/x-wav");
}
if (extensao.equals("gif")) {
response.setContentType("image/gif");
}
if (extensao.equals("jpg") || extensao.equals("jpeg")) {
response.setContentType("image/jpeg");
}
if (extensao.equals("png")) {
response.setContentType("image/png");
}
if (extensao.equals("tiff")) {
response.setContentType("audio/tiff");
}
if (extensao.equals("bmp")) {
response.setContentType("image/x-xbitmap");
}
if (extensao.equals("html") || extensao.equals("htm")) {
response.setContentType("text/html");
}
if (extensao.equals("txt")) {
response.setContentType("text/plain");
}
if (extensao.equals("xml")) {
response.setContentType("text/xml");
}
if (extensao.equals("mpeg")) {
response.setContentType("video/mpeg");
}
Gustavo Marques.
Assim devemos criar um objeto java.io.File com a localizaçao do arquivo que queremos servir e escrevê-lo no HttpServletResponse.
Vamos ao código:
File arquivo = new File("C:\arquivos\relatorio.pdf");
//tipo de arquivo
response.setContentType("application/pdf");
//nome do arquivo a ser exibido na caixa de download do browser
response.setHeader("Content-Disposition", "attachment; filename=" + arquivo.getName()+ ";");
//manda os bytes do arquivo pelo response
URL url = arquivo.toURI().toURL();
BufferedInputStream leitor = new BufferedInputStream(url.openStream(), 4 * 1024);
OutputStream escritor = response.getOutputStream();
byte[] buffer = new byte[4 * 1024];
int size = 0;
while ((size = leitor.read(buffer, 0, buffer.length)) != -1) {
escritor.write(buffer, 0, size);
}
escritor.close();
leitor.close();
Isso fará com que o browser do usuário exiba a caixa de download.
Se você não souber antecipadamente qual o tipo de arquivo que irá entregar, poderá definir em tempo de execução verificando a extensão do arquivo:
//pega a extensão do arquivo
String[] partes = arquivo.getNome().split("\\.");
int ultimaParte = partes.length - 1;
String extensao = partes[ultimaParte];
//seta o content type segundo a extensão
if (extensao.equals("doc")) {
response.setContentType("application/msword");
}
if (extensao.equals("pdf")) {
response.setContentType("application/pdf");
}
if (extensao.equals("pdf")) {
response.setContentType("application/pdf");
}
if (extensao.equals("xls")) {
response.setContentType("application/vnd.ms-excel");
}
if (extensao.equals("ppt")) {
response.setContentType("application/vnd.ms-powerpoint");
}
if (extensao.equals("gzip")) {
response.setContentType("application/gzip");
}
if (extensao.equals("zip")) {
response.setContentType("application/zip");
}
if (extensao.equals("au") || extensao.equals("snd")) {
response.setContentType("audio/basic");
}
if (extensao.equals("midi")) {
response.setContentType("audio/midi");
}
if (extensao.equals("aiff")) {
response.setContentType("audio/x-aiff");
}
if (extensao.equals("wav")) {
response.setContentType("audio/x-wav");
}
if (extensao.equals("gif")) {
response.setContentType("image/gif");
}
if (extensao.equals("jpg") || extensao.equals("jpeg")) {
response.setContentType("image/jpeg");
}
if (extensao.equals("png")) {
response.setContentType("image/png");
}
if (extensao.equals("tiff")) {
response.setContentType("audio/tiff");
}
if (extensao.equals("bmp")) {
response.setContentType("image/x-xbitmap");
}
if (extensao.equals("html") || extensao.equals("htm")) {
response.setContentType("text/html");
}
if (extensao.equals("txt")) {
response.setContentType("text/plain");
}
if (extensao.equals("xml")) {
response.setContentType("text/xml");
}
if (extensao.equals("mpeg")) {
response.setContentType("video/mpeg");
}
Gustavo Marques.
quinta-feira, 1 de novembro de 2012
Criando jogos em HTML 5 utilizando canvas
O html5, principalmente com a funcionalidade de canvas, possibilita a criação de jogos interessantes.
Nesse post mostrarei um exemplo breve de um jogo feito em html 5.
Nesse jogo controlaremos uma nave viajando pelo espaço.
Primeiro precisaremos de 2 imagens: Uma da nave e outra do espaço.
Nesse post eu expliquei como gerar imagens 2d por meio do blender. Vou usar uma como exemplo.
É importante que ela possua fundo transparente (.png).
Agora precisamos da imagem background:
Com essas duas imagens a disposição, já podemos programar nosso jogo.
Vamos ao código.
Para não ter um código sujo, vamos separar o html do javascript em arquivos separados.
jogo.html
<html>
<head>
<title>Jogo</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script>
</head>
<body>
<center>
<h1>Meu Primeiro jogo em html 5</h1>
<br/>
<br/>
<canvas id="game" width="500" height="500" style="border: 1px solid #000000;">
<p>Seu navegador não suporta HTML5!</p>
</canvas>
<script src="codigo.js"></script>
</center>
</body>
</html>
Nesse código temos o elemento <canvas> onde desenharemos com javascript. Agora vamos ao arquivo codigo.js
codigo.js
// cria o contexto grafico no canvas
var drawingCanvas = document.getElementById('game');
var ctx = drawingCanvas.getContext('2d');
var framecount = 0;
// carrega imagens
// Criando Background e seus objetos
var bgReady = false;
var bgImage = new Image();
bgImage.onload = function () {
bgReady = true;
};
bgImage.src = 'bg.jpg';
var naveReady = false;
var naveImage = new Image();
naveImage.onload = function () {
naveReady = true;
};
naveImage.src = 'nave.png';
//objetos do jogo
var nave = {
speed:256,
x:220,
y:440,
w:60,
h:60,
currentImage:null
};
//teclado
var keysDown = {};
addEventListener('keydown', function (e) {
keysDown[e.keyCode] = true;
}, false);
addEventListener('keyup', function (e) {
delete keysDown[e.keyCode];
}, false);
// frame update
var update = function(modifier){
if (38 in keysDown) { // Jogador vai para cima
//verifica se já está no limite
if(nave.y >= 0){
nave.y -= nave.speed * modifier;
}
}
if (40 in keysDown) { // Jogador vai para baixo
if(nave.y <= 500-nave.h){
nave.y += nave.speed * modifier;
}
}
if (37 in keysDown) { // Jogador vai para esquerda
if(nave.x >= 0){
nave.x -= nave.speed * modifier;
}
}
if (39 in keysDown) { // Jogador vai para direita
if(nave.x <= 500 - nave.w){
nave.x += nave.speed * modifier;
}
}
framecount++;
}
//render game
var render = function(){
//clear no canvas
//ctx.fillStyle = 'rgb(1, 1, 1)';
//ctx.fillRect(0, 0, 500, 500);
if (bgReady) {
ctx.drawImage(bgImage, 0, 0);
}
if (naveReady) {
ctx.drawImage(naveImage, nave.x, nave.y);
}
// pinta o framecount
ctx.fillStyle = 'rgb(250, 250, 250)';
ctx.font = '10px Verdana';
ctx.textAlign = 'left';
ctx.textBaseline = 'top';
ctx.fillText('Frame: ' + framecount, 390, 480);
}
//função que irá controlar o game loop
var main = function () {
var now = Date.now();
var delta = now - then;
update(delta / 1000);
render();
then = now;
};
//iniciando o game
var then = Date.now();
setInterval(main, 1);
Não se assuste! Leia os comentários que está bem claro. Veja as explicações abaixo na ordem dos comentários:
1- Iniciamos o contexto do canvas.
2- Carregamos as imagens do jogo. Observe que coloquei 2 variáveis booleanas para saber quando as imagens foram carregadas e assim poder pintalas no canvas.
3- Criamos o objeto nave (sprite) com as propriedades de localização no canvas e suas dimensões.
4- Registramos as teclas pressionadas.
5- Entramos agora na função update. Ela será executada a cada frame. Se você não entende esse conceito de frame e game loop leia esse post. Dentro da função update atualizamos a posição da nave, verificando sempre se ela já atingiu o limite do cenário. A variavel framecont eu adicionei só para vocês observarem que durante um jogo o game loop acontece. Ela vai sendo incrementada e exibida a cada frame.
6- A função render é responsável por pintar na tela o estado atual do jogo, nesse caso a posição atual da nave. Observe que pintamos utilizando os métodos de ctx. Ele funciona como o graphics do java 2d.
7- A função main é o game loop. Ela será executada no intervalo definido na ultima linha setInterval();
Gustavo Marques
Nesse post mostrarei um exemplo breve de um jogo feito em html 5.
Nesse jogo controlaremos uma nave viajando pelo espaço.
Primeiro precisaremos de 2 imagens: Uma da nave e outra do espaço.
Nesse post eu expliquei como gerar imagens 2d por meio do blender. Vou usar uma como exemplo.
É importante que ela possua fundo transparente (.png).
Agora precisamos da imagem background:
Com essas duas imagens a disposição, já podemos programar nosso jogo.
Vamos ao código.
Para não ter um código sujo, vamos separar o html do javascript em arquivos separados.
jogo.html
<html>
<head>
<title>Jogo</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script>
</head>
<body>
<center>
<h1>Meu Primeiro jogo em html 5</h1>
<br/>
<br/>
<canvas id="game" width="500" height="500" style="border: 1px solid #000000;">
<p>Seu navegador não suporta HTML5!</p>
</canvas>
<script src="codigo.js"></script>
</center>
</body>
</html>
Nesse código temos o elemento <canvas> onde desenharemos com javascript. Agora vamos ao arquivo codigo.js
codigo.js
// cria o contexto grafico no canvas
var drawingCanvas = document.getElementById('game');
var ctx = drawingCanvas.getContext('2d');
var framecount = 0;
// carrega imagens
// Criando Background e seus objetos
var bgReady = false;
var bgImage = new Image();
bgImage.onload = function () {
bgReady = true;
};
bgImage.src = 'bg.jpg';
var naveReady = false;
var naveImage = new Image();
naveImage.onload = function () {
naveReady = true;
};
naveImage.src = 'nave.png';
//objetos do jogo
var nave = {
speed:256,
x:220,
y:440,
w:60,
h:60,
currentImage:null
};
//teclado
var keysDown = {};
addEventListener('keydown', function (e) {
keysDown[e.keyCode] = true;
}, false);
addEventListener('keyup', function (e) {
delete keysDown[e.keyCode];
}, false);
// frame update
var update = function(modifier){
if (38 in keysDown) { // Jogador vai para cima
//verifica se já está no limite
if(nave.y >= 0){
nave.y -= nave.speed * modifier;
}
}
if (40 in keysDown) { // Jogador vai para baixo
if(nave.y <= 500-nave.h){
nave.y += nave.speed * modifier;
}
}
if (37 in keysDown) { // Jogador vai para esquerda
if(nave.x >= 0){
nave.x -= nave.speed * modifier;
}
}
if (39 in keysDown) { // Jogador vai para direita
if(nave.x <= 500 - nave.w){
nave.x += nave.speed * modifier;
}
}
framecount++;
}
//render game
var render = function(){
//clear no canvas
//ctx.fillStyle = 'rgb(1, 1, 1)';
//ctx.fillRect(0, 0, 500, 500);
if (bgReady) {
ctx.drawImage(bgImage, 0, 0);
}
if (naveReady) {
ctx.drawImage(naveImage, nave.x, nave.y);
}
// pinta o framecount
ctx.fillStyle = 'rgb(250, 250, 250)';
ctx.font = '10px Verdana';
ctx.textAlign = 'left';
ctx.textBaseline = 'top';
ctx.fillText('Frame: ' + framecount, 390, 480);
}
//função que irá controlar o game loop
var main = function () {
var now = Date.now();
var delta = now - then;
update(delta / 1000);
render();
then = now;
};
//iniciando o game
var then = Date.now();
setInterval(main, 1);
Não se assuste! Leia os comentários que está bem claro. Veja as explicações abaixo na ordem dos comentários:
1- Iniciamos o contexto do canvas.
2- Carregamos as imagens do jogo. Observe que coloquei 2 variáveis booleanas para saber quando as imagens foram carregadas e assim poder pintalas no canvas.
3- Criamos o objeto nave (sprite) com as propriedades de localização no canvas e suas dimensões.
4- Registramos as teclas pressionadas.
5- Entramos agora na função update. Ela será executada a cada frame. Se você não entende esse conceito de frame e game loop leia esse post. Dentro da função update atualizamos a posição da nave, verificando sempre se ela já atingiu o limite do cenário. A variavel framecont eu adicionei só para vocês observarem que durante um jogo o game loop acontece. Ela vai sendo incrementada e exibida a cada frame.
6- A função render é responsável por pintar na tela o estado atual do jogo, nesse caso a posição atual da nave. Observe que pintamos utilizando os métodos de ctx. Ele funciona como o graphics do java 2d.
7- A função main é o game loop. Ela será executada no intervalo definido na ultima linha setInterval();
Gustavo Marques
terça-feira, 30 de outubro de 2012
Inserindo conteúdo dinâmico com JQuery
A biblioteca jquery facilita muito o trabalho em tornar nossas interfaces mais interativas.
Nesse exemplo mostrarei como adicionar conteúdo dinamicamente na página.
Essa funcionalidade é importante em várias situações, como adicionar novos itens, novos campos para preenchimento etc.
Nesse exemplo vamos inserir novos campos de preenchimento de um cadastro
Vamos ao código:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script>
</head>
<body>
<input onclick="$('#conteudo').append('Novo Item: <input type=text /><br/>');" type="button" value="Adicione mais itens" />
<div id="conteudo"></div>
</body>
</html>
Testando o código:
O Evento onclick do input irá acionar o método append do jquery, esse método adiciona um conteudo dentro e ao final de um elemento.
Adapte esse exemplo a suas necessidades,
Gustavo Marques.
Nesse exemplo mostrarei como adicionar conteúdo dinamicamente na página.
Essa funcionalidade é importante em várias situações, como adicionar novos itens, novos campos para preenchimento etc.
Nesse exemplo vamos inserir novos campos de preenchimento de um cadastro
Vamos ao código:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script>
</head>
<body>
<input onclick="$('#conteudo').append('Novo Item: <input type=text /><br/>');" type="button" value="Adicione mais itens" />
<div id="conteudo"></div>
</body>
</html>
Testando o código:
O Evento onclick do input irá acionar o método append do jquery, esse método adiciona um conteudo dentro e ao final de um elemento.
Adapte esse exemplo a suas necessidades,
Gustavo Marques.
| Veja mais detalhes |
terça-feira, 16 de outubro de 2012
Como recortar um pedaço de uma imagem (crop) utilizando javascript e PHP
Muitos sistemas precisam guardar as fotos de seus usuários. O problema é que o usuário final raramente terá uma foto nas dimensões adequadas (e mais dificilmente ainda ele abrirá a imagem disponível em um software grafico para dar um resize), de modo que é interessante oferecer a funcionalidade de crop na foto que subiu via upload. Crop significa recortar um pedaço da imagem.
Recentemente em um projeto tive que implementar essa função.
Segue os prints:
Step 1: O usuario seleciona uma foto qualquer em seu computador
Step 2: O usuário é redirecionado para a página de recorte (crop) da imagem que ele enviou
Step 3: O pedaço da imagem que ele recortou será usado para representá-lo no sistema.
Vamos ao código:
Primeiro vamos precisar de uma lib javascript que faz crop, tem várias.
A que eu escolhi é esta aqui: http://uvumitools.com/crop.html
Pegue todos os arquivos e coloque em seu projeto
Crie uma página PHP com um formulário para o upload da imagem:
<form action="upload.php?user_id=2353" enctype="multipart/form-data" method="POST">
<input id="fileInput" name="arquivos" type="file" />
<input type="submit" value="Salvar Foto" />
</form>
Agora crie o arquivo upload.php que irá receber esse upload vindo do form:
$destino = 'C:\xampp\htdocs\site\uploads';//estou usando a pasta uploads para guardar os arquivos
if (!$_FILES) {
echo 'Nenhum arquivo enviado!';
} else {
$file_name = $_FILES['arquivos']['name'];
$file_type = $_FILES['arquivos']['type'];
$file_size = $_FILES['arquivos']['size'];
$file_tmp_name = $_FILES['arquivos']['tmp_name'];
$error = $_FILES['arquivos']['error'];
}
switch ($error) {
case 0:
break;
case 1:
echo 'Tamanho do arquivo ultrapassou o limite';
break;
case 2:
echo 'O tamanho do arquivo é maior do que o permitido!';
break;
case 3:
echo 'O upload não foi concluído!';
break;
case 4:
echo 'O upload não foi feito!';
break;
}
if ($error == 0) {
if (!is_uploaded_file($file_tmp_name)) {
echo 'Erro ao processar arquivo!';
} else {
//concateno o time no nome do arquivo para evitar sobrescrever arquivos de mesmo nome
$time = time();
if (!move_uploaded_file($file_tmp_name, $destino . "/" . $time.$file_name)) {
echo 'Não foi possível salvar o arquivo!';
} else {
//vai para o crop
require_once 'crop_editor.php';//carrega aqui a página que faz o crop
}
}
}
O arquivo crop_editor.php:
Certifique-se de que esses arquivos js e css estejam nos locais apropriados.
<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="js/jquery-1.3.2.min.js" type="text/javascript"></script>
<script src="js/mootools-for-crop.js" type="text/javascript"> </script>
<script src="js/UvumiCrop-compressed.js" type="text/javascript"> </script>
<link href="css/uvumi-crop.css" media="screen" rel="stylesheet" type="text/css"></link>
<style type="text/css">
body,html{
background-color:#333;
margin:0;
padding:0;
font-family:Trebuchet MS, Helvetica, sans-serif;
}
hr{
margin:20px 0;
}
#main{
margin:5%;
position:relative;
overflow:auto;
color:#aaa;
padding:20px;
border:1px solid #888;
background-color:#000;
text-align:center;
}
#resize_coords{
width:50px;
}
#previewExample3{
margin:10px;
}
.yellowSelection{
border: 2px dotted #FFB82F;
}
.blueMask{
background-color:#00f;
cursor:pointer;
}
</style>
<script type="text/javascript">
exampleCropper1 = new uvumiCropper('imagem',{
coordinates:false,
preview:true,
downloadButton:false,
saveButton:true,
serverScriptSave:'crop_it.php', //aqui a pagina que recebe os parametros do crop
onCropSuccess:function(){
document.location = 'sucesso.php';
},
onCropFail:function(){
document.location = 'error.php';
},
mini:{
x:150,
y:150
},
parameters:{
usuario_id:'<?php echo $_REQUEST['user_id']?>'
}
});
</script>
</head>
<body>
<div>
<img alt="cropping test" id="imagem" src="uploads/?php echo $time . $file_name;?" />
</div>
<div id="saida">
</div>
</body>
</html>
Agora a página crop_it.php:
$h=$_REQUEST['height'];
$x=$_REQUEST['left'];
$y=$_REQUEST['top'];
$filename=$_REQUEST['filename'];
header('Content-type: image/jpg');
//header('Content-Disposition: attachment; filename='.$src);
$image = imagecreatefromjpeg('uploads/'.$filename);
$crop = imagecreatetruecolor($w,$h);
imagecopy ( $crop, $image, 0, 0, $x, $y, $w, $h );
imagejpeg($crop);
Pronto, aparecerá somente o pedaço escolhido.
Você pode fazer alterações nesse arquivo, como por exemplo salvar em disco o pedaço da imagem e associar o nome dessa nova imagem ao usuário no banco de dados. Repare que desde o formulário estou passando o id do usuario, você pode recuperá-lo aqui usando $_REQUEST['usuario_id'], ou pegar da sessão.
Espero que esse exemplo ajude.
atenciosamente,
Gustavo Marques.
Recentemente em um projeto tive que implementar essa função.
Segue os prints:
Step 1: O usuario seleciona uma foto qualquer em seu computador
Step 3: O pedaço da imagem que ele recortou será usado para representá-lo no sistema.
Vamos ao código:
Primeiro vamos precisar de uma lib javascript que faz crop, tem várias.
A que eu escolhi é esta aqui: http://uvumitools.com/crop.html
Pegue todos os arquivos e coloque em seu projeto
Crie uma página PHP com um formulário para o upload da imagem:
<form action="upload.php?user_id=2353" enctype="multipart/form-data" method="POST">
<input id="fileInput" name="arquivos" type="file" />
<input type="submit" value="Salvar Foto" />
</form>
Agora crie o arquivo upload.php que irá receber esse upload vindo do form:
$destino = 'C:\xampp\htdocs\site\uploads';//estou usando a pasta uploads para guardar os arquivos
if (!$_FILES) {
echo 'Nenhum arquivo enviado!';
} else {
$file_name = $_FILES['arquivos']['name'];
$file_type = $_FILES['arquivos']['type'];
$file_size = $_FILES['arquivos']['size'];
$file_tmp_name = $_FILES['arquivos']['tmp_name'];
$error = $_FILES['arquivos']['error'];
}
switch ($error) {
case 0:
break;
case 1:
echo 'Tamanho do arquivo ultrapassou o limite';
break;
case 2:
echo 'O tamanho do arquivo é maior do que o permitido!';
break;
case 3:
echo 'O upload não foi concluído!';
break;
case 4:
echo 'O upload não foi feito!';
break;
}
if ($error == 0) {
if (!is_uploaded_file($file_tmp_name)) {
echo 'Erro ao processar arquivo!';
} else {
//concateno o time no nome do arquivo para evitar sobrescrever arquivos de mesmo nome
$time = time();
if (!move_uploaded_file($file_tmp_name, $destino . "/" . $time.$file_name)) {
echo 'Não foi possível salvar o arquivo!';
} else {
//vai para o crop
require_once 'crop_editor.php';//carrega aqui a página que faz o crop
}
}
}
O arquivo crop_editor.php:
Certifique-se de que esses arquivos js e css estejam nos locais apropriados.
<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="js/jquery-1.3.2.min.js" type="text/javascript"></script>
<script src="js/mootools-for-crop.js" type="text/javascript"> </script>
<script src="js/UvumiCrop-compressed.js" type="text/javascript"> </script>
<link href="css/uvumi-crop.css" media="screen" rel="stylesheet" type="text/css"></link>
<style type="text/css">
body,html{
background-color:#333;
margin:0;
padding:0;
font-family:Trebuchet MS, Helvetica, sans-serif;
}
hr{
margin:20px 0;
}
#main{
margin:5%;
position:relative;
overflow:auto;
color:#aaa;
padding:20px;
border:1px solid #888;
background-color:#000;
text-align:center;
}
#resize_coords{
width:50px;
}
#previewExample3{
margin:10px;
}
.yellowSelection{
border: 2px dotted #FFB82F;
}
.blueMask{
background-color:#00f;
cursor:pointer;
}
</style>
<script type="text/javascript">
exampleCropper1 = new uvumiCropper('imagem',{
coordinates:false,
preview:true,
downloadButton:false,
saveButton:true,
serverScriptSave:'crop_it.php', //aqui a pagina que recebe os parametros do crop
onCropSuccess:function(){
document.location = 'sucesso.php';
},
onCropFail:function(){
document.location = 'error.php';
},
mini:{
x:150,
y:150
},
parameters:{
usuario_id:'<?php echo $_REQUEST['user_id']?>'
}
});
</script>
</head>
<body>
<div>
<img alt="cropping test" id="imagem" src="uploads/?php echo $time . $file_name;?" />
</div>
<div id="saida">
</div>
</body>
</html>
Agora a página crop_it.php:
$h=$_REQUEST['height'];
$x=$_REQUEST['left'];
$y=$_REQUEST['top'];
$filename=$_REQUEST['filename'];
header('Content-type: image/jpg');
//header('Content-Disposition: attachment; filename='.$src);
$image = imagecreatefromjpeg('uploads/'.$filename);
$crop = imagecreatetruecolor($w,$h);
imagecopy ( $crop, $image, 0, 0, $x, $y, $w, $h );
imagejpeg($crop);
Pronto, aparecerá somente o pedaço escolhido.
Você pode fazer alterações nesse arquivo, como por exemplo salvar em disco o pedaço da imagem e associar o nome dessa nova imagem ao usuário no banco de dados. Repare que desde o formulário estou passando o id do usuario, você pode recuperá-lo aqui usando $_REQUEST['usuario_id'], ou pegar da sessão.
Espero que esse exemplo ajude.
atenciosamente,
Gustavo Marques.
Assinar:
Postagens (Atom)




