1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
| #!/usr/bin/env perl
use v5.36;
use Devel::Size qw(total_size);
package BulletType {
use Moo;
has shape => (is => 'ro', required => 1);
has color => (is => 'ro', required => 1);
has size => (is => 'ro', required => 1);
has char => (is => 'ro', required => 1);
sub render($self, $x, $y) {
my $char = $self->char;
print "$char";
}
}
package BulletFactory {
use Moo;
has _cache => (is => 'ro', default => sub { {} });
has _definitions => (
is => 'ro',
default => sub {
{
red_circle => { shape => 'circle', color => 'red', size => 8, char => '●' },
blue_star => { shape => 'star', color => 'blue', size => 12, char => '★' },
green_laser => { shape => 'laser', color => 'green', size => 4, char => '|' },
yellow_arrow => { shape => 'arrow', color => 'yellow', size => 6, char => '→' },
purple_wave => { shape => 'wave', color => 'purple', size => 10, char => '〜' },
}
},
);
sub get($self, $type_key) {
my $cache = $self->_cache;
my $defs = $self->_definitions;
$cache->{$type_key} //= do {
my $def = $defs->{$type_key}
or die "Unknown bullet type: $type_key";
BulletType->new(%$def);
};
return $cache->{$type_key};
}
sub cache_count($self) {
return scalar(keys %{$self->_cache});
}
}
# 弾幕を生成
my $factory = BulletFactory->new;
my @type_keys = qw(red_circle blue_star green_laser yellow_arrow purple_wave);
my @bullets;
for my $i (0 .. 999) {
# 5種類の弾をランダムに配置
my $type_key = $type_keys[$i % 5];
push @bullets, {
type => $factory->get($type_key),
x => $i % 50,
y => int($i / 50),
vx => 0,
vy => 1,
};
}
say "=== 弾幕の統計 ===";
say "弾の総数: " . scalar(@bullets);
say "BulletTypeオブジェクトの数: " . $factory->cache_count;
say "";
# メモリ使用量を確認
my $bullets_size = total_size(\@bullets);
my $cache_size = total_size($factory->_cache);
say "=== メモリ使用量 ===";
say "弾1000発分: " . sprintf("%.1f", $bullets_size / 1024) . "KB";
say "BulletType 5つ分: " . sprintf("%.1f", $cache_size / 1024) . "KB";
say "";
# 弾幕を20x10の範囲で描画(一部だけ)
say "=== 弾幕プレビュー(先頭200発)===";
for my $row (0 .. 3) {
for my $col (0 .. 49) {
my $idx = $row * 50 + $col;
my $bullet = $bullets[$idx];
$bullet->{type}->render($bullet->{x}, $bullet->{y});
}
say "";
}
|