27/11/2009, 22:56
|
|
#1
|
|
Member
Join Date: Sep 2008
Location: jogja
Posts: 245
|
2d tree generator beta
versi terbaru
demo 7 mei 2010
males nggambar pohon?
file pohon-pohon makan banyak storage?
class ini bertujuan untuk menggenerate pohon secara random.
gak percaya? liat ndiri
1. fps test. meng-generate 1 pohon per frame. total 30 pohon(click to watch)
2. nyoba ngenerate? click untuk menggenerate pohon baru.(click to watch)
ini code-nya
Code:
/*
* 2D procedural tree (proceduralTree beta)
* Part of Cornicle Game Development Kit
*
* Copyright (c) 2009 Kornelius Heru C.M, All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package cornicleProceduralTree
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.filters.GlowFilter;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
/**
* ...
* @author cornicle
*/
public class proceduralTree extends Sprite
{
private var bark:BitmapData;
private var leaf:BitmapData;
private var result:MovieClip;
private var maxLeaf:Number;
public function proceduralTree(bark:BitmapData, leaf:BitmapData, outline:Boolean, firstLength:Number, maxBranch:Number, minBranch:Number, maxLeaf:Number) {
//setting up textures
this.bark = bark;
this.leaf = leaf;
//our render target
result = new MovieClip();
//generate new tree
this.maxLeaf = maxLeaf;
generateNewTree(firstLength, maxBranch, minBranch);
//getting the bounding box
var rect:Rectangle = result.getRect(result);
//create new bitmap where we draw our movieclip. drawing a complex movieclip eats more memory than a bitmap;
var treeBitmap:BitmapData = new BitmapData(rect.width, rect.height, true, 0x00000000);
//some simple texture translation
var mat:Matrix = new Matrix();
mat.translate( -rect.x, -rect.y);
//use outline?
if(outline){
var glow:GlowFilter = new GlowFilter(0x000000, 100, 1, 1, 5, 1);
var filters:Array = new Array();
filters.push(glow);
result.filters = filters;
}
//draw our tree to bitmap
treeBitmap.draw(result, mat);
var bmp:Bitmap = new Bitmap(treeBitmap);
bmp.y = -rect.height;
bmp.x = -rect.width/2;
this.addChild(bmp);
//finaly clear our movieClip. we don't need it anymore.
result.graphics.clear();
}
public function generateNewTree(firstLength:Number, maxBranch:Number, minBranch:Number):MovieClip {
result.graphics.clear();
generateTree(firstLength, maxBranch, minBranch, 0, 0, null, null);
return result;
}
public function generateTree(firstLength:Number, maxBranch:Number, minBranch:Number, x:Number, y:Number, pt1:Point, pt2:Point):void {
var rotation:Number = -Math.PI/2 + Math.random() * Math.PI + Math.PI;
var length:Number = Math.max(Math.random() * firstLength, firstLength/2);
var hThickness:Number = length / 10;
var branch:Number = Math.max(Math.round(Math.random() * maxBranch), minBranch);
//brach's geometry
// p3------p2
// | /|
// | / |
// | / |
// | / |
// | / |
// |/ |
// p0------p1
var p0:Point;
if (pt1 == null) {
p0 = new Point( hThickness, 0);
}else {
p0 = pt1;
}
var p1:Point;
if (pt2 == null) {
p1 = new Point(-hThickness , 0);
}else {
p1 = pt2;
}
var p2:Point;
var p3:Point;
if (branch > 0) {
p2 = new Point(hThickness / 2, length);
p3 = new Point( -hThickness / 2, length);
}else {
p2 = new Point(0 , length);
p3 = new Point(0 , length);
}
//setup final transformation
var mat:Matrix = new Matrix();
mat.rotate(rotation);
mat.translate(x, y);
//update real position
p2 = mat.transformPoint(p2);
p3 = mat.transformPoint(p3);
//setup texture matrix
var textureMatrix:Matrix = new Matrix();
textureMatrix.translate(bark.width / 2, 0);
textureMatrix.scale(hThickness / bark.width, length / 2 / bark.height);
textureMatrix.rotate(rotation);
//draw branch
//result.graphics.lineStyle(1, 0x000000);
result.graphics.beginBitmapFill(bark, textureMatrix);
result.graphics.moveTo(p0.x, p0.y);
result.graphics.lineTo(p1.x, p1.y);
result.graphics.lineTo(p2.x, p2.y);
result.graphics.lineTo(p3.x, p3.y);
result.graphics.endFill();
//not for the root
if((pt1 != null)&&(pt2 != null)){
//draw leafs
var numLeaves:Number = Math.round(Math.random() * maxLeaf);
var leafS:Point = new Point((p1.x + p0.x) / 2, (p1.y + p0.y) / 2);
var leafF:Point = new Point((p3.x + p2.x) / 2, (p3.y + p2.y) / 2);
var dx:Number = leafF.x - leafS.x;
var dy:Number = leafF.y - leafS.y;
// create leafs
for (var j:Number = 0 ; j < numLeaves ; j++) {
//leaf position
var newPos:Point = new Point(leafS.x + Math.random() * dx , leafS.y + Math.random() * dy);
var leafSize:Number = Math.max( 25 * Math.random(), length / 4);
//leaf's geometry
// l0----------l1
// | /|
// | / |
// | / |
// | / |
// | / |
// |/ |
// l3----------l2
//drawing points
var l0:Point = new Point(-leafSize, -leafSize);
var l1:Point = new Point( leafSize, -leafSize);
var l2:Point = new Point( leafSize, leafSize);
var l3:Point = new Point(-leafSize, leafSize);
var lMat:Matrix = new Matrix();
lMat.translate(newPos.x, newPos.y);
// transforming points
l0 = lMat.transformPoint(l0);
l1 = lMat.transformPoint(l1);
l2 = lMat.transformPoint(l2);
l3 = lMat.transformPoint(l3);
//texture matrix
var lTMat:Matrix = new Matrix();
var scale:Number = leafSize / leaf.width * 2;
lTMat.translate((newPos.x - leafSize) / scale, (newPos.y - leafSize) / scale);
lTMat.scale(scale , scale);
//drawing
result.graphics.beginBitmapFill(leaf, lTMat);
result.graphics.moveTo(l0.x, l0.y);
result.graphics.lineTo(l1.x, l1.y);
result.graphics.lineTo(l2.x, l2.y);
result.graphics.lineTo(l3.x, l3.y);
result.graphics.endFill();
}
}
//proceed to next branches
for (var i:Number = 0; i < branch ; i++) {
var n1:Point;
var n2:Point;
if (p3.x < p2.x) {
n1 = p2;
n2 = p3;
}else {
n1 = p3;
n2 = p2
}
var nextPosition:Point = new Point((p3.x + p2.x) / 2, (p3.y + p2.y) / 2);
generateTree(length, branch - 1, minBranch - 1, nextPosition.x, nextPosition.y, n1, n2);
}
}
}
}
cara pakenya?
importkan kemudian panggil constructornya. yang dibutuhkan adalah 2 gambar sebagai texture yang terdiri dari, satu texture daun 64 x 64 pixel, dan satu texture batang 64 x 64. resolusi yang lain belum saya coba.
Code:
var pt:proceduralTree = new proceduralTree(bark1.bitmapData, daun1.bitmapData, false, 200, 8, 4, 3);
parameter 1 : bark1 adalah texture batang,
parameter 2 : daun1 adalah texture daun,
parameter 3 : false, use outline?
parameter 4 : 200, pangjang / scale dari batang terbesar(dirandom)
parameter 5 : 8, maximal branch
parameter 6 : 4, minimal branch
parameter 7 : 3, maximal daun per batang.
simple kan?
contoh class main-nya. jangan lupa untuk import proceduralTree.as -nya
Code:
package
{
import cornicleProceduralTree.proceduralTree;
import flash.display.Bitmap;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.system.System;
/**
* ...
* @author cornicle
*/
public class Main extends Sprite
{
[Embed(source = 'texture/bark1.jpg')]
public static var Bark1:Class;
[Embed(source = 'texture/daun.png')]
public static var Daun1:Class;
public var text:TextField;
public var daun1:Bitmap;
public var bark1:Bitmap;
public var pt:proceduralTree
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
var mc:MovieClip = new MovieClip();
mc.graphics.beginFill(0xccccff, 100);
mc.graphics.moveTo(0, 0);
mc.graphics.lineTo(800, 0);
mc.graphics.lineTo(800, 600);
mc.graphics.lineTo(0, 600);
addChild(mc);
text = new TextField();
this.addChild(text);
text.textColor = 0x000000;
text.width = 400;
text.text = "2D procedural tree Beta.\ncreating 30 random generated trees";
bark1 = new Bark1();
daun1 = new Daun1();
update(null);
addEventListener(MouseEvent.CLICK, update);
}
public function update(e:Event):void {
if (pt) {
removeChild(pt)
}
pt = new proceduralTree(bark1.bitmapData, daun1.bitmapData, false, 200, 8, 4, 3);
addChild(pt);
pt.x = 400;
pt.y = 600;
text.text = "2D procedural tree Beta.\nclick any where to generate new tree\neating "+ Math.round(System.totalMemory/(1024*1024)) + " MB";
}
}
}
__________________
PROMISED LAND
a place, where a game programmer. siting in front of a super computer. beside a million tons of beer
ready to drink.
- my works -
Last edited by kornwaretm : 07/05/2010 at 11:08.
|
|
28/11/2009, 09:04
|
|
#2
|
|
Alien dari lab GAIB
Join Date: Jul 2005
Location: lab gaib itb, bandung
Posts: 1,755
|
kyknya orientasi batang pertama mesti agak dibatesin deh.. biar nggak kayak jatoh
|
|
28/11/2009, 13:15
|
|
#3
|
|
Veteran Member
Join Date: Feb 2007
Location: deket bunderan kampus
Posts: 1,422
|
jadi ingat ama pohon yang rekursif jaman dulu
karena murni random, jadi kesannya kurang natural.
mungkin bisa pakai semacam pattern biar bisa bikin pohon dengan jenis macam-macam seperti kelapa, cemara, monokotil, dikotil, paku-pakuan, dll
biasanya bikin pohon tuh pakai semacam kanopi bank yang disusun menurut pola tertentu secara acak.
sambungan batang terkadang tampak kecil kayak kertas dilipat, ukurannya perlu diperhatikan.
|
|
28/11/2009, 16:33
|
|
#4
|
|
GDI Power Users
Join Date: Dec 2007
Location: Pangkalpinang
Posts: 3,279
|
hmmm... mayan... coba diimplement yang dikatain om real pasti makin muangstab 
__________________
tobat ngejunk. tobat nyepam. tobat bikin yang gak bener. tobat kasih komen gak jelas. tobat buang-buang ikon. tobat jadi orang jelek. tobat maen komputer sambil belajar. tobat banget kalo ngomong gak bertanggung jawab. tobat banget untuk kesalahan laennya.
"siapa yang mau ikut2an tobat??"
blog : http://alijaya.wordpress.com/, http://bothaxe.wordpress.com/
|
|
28/11/2009, 21:01
|
|
#5
|
|
Member
Join Date: Sep 2008
Location: jogja
Posts: 245
|
Quote:
Originally Posted by pe-e-be
kyknya orientasi batang pertama mesti agak dibatesin deh.. biar nggak kayak jatoh
|
stuju. oke deh kalo begitu. mbuka flash develop
Quote:
Originally Posted by realtime
jadi ingat ama pohon yang rekursif jaman dulu
karena murni random, jadi kesannya kurang natural.
mungkin bisa pakai semacam pattern biar bisa bikin pohon dengan jenis macam-macam seperti kelapa, cemara, monokotil, dikotil, paku-pakuan, dll
biasanya bikin pohon tuh pakai semacam kanopi bank yang disusun menurut pola tertentu secara acak.
sambungan batang terkadang tampak kecil kayak kertas dilipat, ukurannya perlu diperhatikan.
|
iya ini pohon recursif tapi 2D
waduh pattern? .serem.... semacam gramar untuk pohon ya?  ?
ato jangan-jangan butuh genetic algoritm?
kayaknya bakal mengakibatkan pembengkakan resource. dan belum yakin kecepatan generate-nya. (*,)
oke deh kalo begitu. mbuka google.
Quote:
Originally Posted by alijaya
hmmm... mayan... coba diimplement yang dikatain om real pasti makin muangstab 
|
selamat implementasi.
kalo pake c++ fungsi random kan selalu mengembalikan nilai yang sama tergantung dari srand() ya kan? AS3 bisa semacam ini gak ya?
__________________
PROMISED LAND
a place, where a game programmer. siting in front of a super computer. beside a million tons of beer
ready to drink.
- my works -
|
|
07/05/2010, 10:12
|
|
#6
|
|
Member
Join Date: Sep 2008
Location: jogja
Posts: 245
|
new update
1. pembatasan kedalaman rekrusi
2. penggunaan grammar batang dan daun
3. sudah tidak extends sprite,
4. murni generator pohon, dan menghasilkan bitmapData
demo
__________________
PROMISED LAND
a place, where a game programmer. siting in front of a super computer. beside a million tons of beer
ready to drink.
- my works -
|
|
07/05/2010, 10:33
|
|
#7
|
|
Veteran Member
Join Date: Feb 2007
Location: deket bunderan kampus
Posts: 1,422
|
love the sky 
|
|
07/05/2010, 11:42
|
|
#8
|
|
Susu Kedele Basi
Join Date: Dec 2006
Location: Mt.Merapi
Posts: 2,366
|
wogh... mantap gan! posisi daun udah lebih pas.. cobain ah
yang generate 30, mayan cepet juga. pake object pool? gc-nya keliatan bekerja
nice work!
|
|
07/05/2010, 12:10
|
|
#9
|
|
Member
Join Date: Sep 2008
Location: jogja
Posts: 245
|
@om soy
gak pake object pool, tapi bisa tinggal biki array untuk menampung hasil generation-nya. source code menyusul. tadi lupa bawa.
__________________
PROMISED LAND
a place, where a game programmer. siting in front of a super computer. beside a million tons of beer
ready to drink.
- my works -
|
|
07/05/2010, 17:35
|
|
#10
|
|
GDI Power Users
Join Date: Dec 2007
Location: Pangkalpinang
Posts: 3,279
|
wah mangstab 
ntuh background gimana bikinna???? mangstab neh 
btw... soal tree generator, aku ada link mayan bagus neh http://en.wikipedia.org/wiki/L-system
__________________
tobat ngejunk. tobat nyepam. tobat bikin yang gak bener. tobat kasih komen gak jelas. tobat buang-buang ikon. tobat jadi orang jelek. tobat maen komputer sambil belajar. tobat banget kalo ngomong gak bertanggung jawab. tobat banget untuk kesalahan laennya.
"siapa yang mau ikut2an tobat??"
blog : http://alijaya.wordpress.com/, http://bothaxe.wordpress.com/
|
|
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|